結局、NodeJS+V8に押された形で、JavaScript(Chakrart)のネイティブアプリ採用を公に認めた。
今までは煮え切らない態度で、IActiveScriptを作ったもののそれ以上何もしてこなかった。
セキュリティの問題が発生しやすいので、本当はあまりプッシュしたくないのだろうと思う。

JSRTサンプルにあるechoという手抜きしている関数を直したechoexを作成。

JavaScript Runtime Hosting Sample


var b = {"a":1, "b":2, "c":[1,2,3] };
host.echo(b); // [object Object]
host.echoex(b); // {a:1, b:2, c:[1,2,3]}


#include "stdafx.h"
#include
#include
#include
#include
#include

void ValueVariantToString( std::wstringstream& sm, VARIANT& v );


JsValueRef CALLBACK EchoEx(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
{
for (unsigned int index = 1; index < argumentCount; index++)
{
if (index > 1)
{
wprintf(L" ");
}

_variant_t vx;
JsValueRef x = arguments[index];
JsValueToVariant(x, &vx );

std::wstringstream sm;

ValueVariantToString( sm, vx );

wprintf( sm.str().c_str() );
}
wprintf(L"\n");

return JS_INVALID_REFERENCE;
}

HRESULT InvokeGetProperty( IDispatch* disp, DISPID id, VARIANT& val )
{
EXCEPINFO ex; UINT er; DISPPARAMS pm = { NULL,0,0,0 };
return disp->Invoke( id, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &pm, &val, &ex, &er );
}
HRESULT InvokeGetDISPID( IDispatch* disp, LPCWSTR nm, DISPID& id )
{
LPOLESTR nma[1]; nma[0] = (LPOLESTR)nm;

return disp->GetIDsOfNames( IID_NULL, nma, 1,LOCALE_USER_DEFAULT, &id );
}
HRESULT InvokeGetProperty( IDispatch* disp, LPCWSTR nm, VARIANT& val )
{
DISPID id;
HRESULT hr = InvokeGetDISPID( disp, nm, id );
if ( SUCCEEDED(hr))
hr = InvokeGetProperty( disp, id, val );
return hr;
}


static void ValueVariantToString( std::wstringstream& sm, VARIANT& v )
{
if ( v.vt == VT_DISPATCH )
{
IDispatch* disp = v.pdispVal;

DISPPARAMS pm = {NULL,0,0,0};

CComPtr px;
auto hr = disp->QueryInterface( &px );
_ASSERT( hr == S_OK );

_variant_t v;
hr = InvokeGetProperty( disp, L"length", v );
if ( hr == S_OK && v.vt == VT_I4 )
{
sm << L"[";
for( LONG i = 0; i < v.intVal; i++ )
{
if ( i != 0 )
sm << L", ";

DISPPARAMS dispParamsNoArgs = {0};

WCHAR strIndex[64];
wsprintf( strIndex, L"%d", i);

// Convert to BSTR, as GetDispID() wants BSTR's
CComBSTR bstrIndex(strIndex);
DISPID dispidIndex;
hr = px->GetDispID(bstrIndex, fdexNameCaseSensitive, &dispidIndex);
if (FAILED(hr))
break;

// Get array item value using InvokeEx()
CComVariant varItem;
hr = px->InvokeEx(dispidIndex, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParamsNoArgs, &varItem, // Arrayからデータゲット
NULL, NULL);

if (FAILED(hr))
break;

ValueVariantToString( sm, varItem );


}
sm << L"]";
}
else
{
// 多分 key-value
DISPID dispid;

sm << L"{";
int i = 0;

HRESULT hr = px->GetNextDispID(fdexEnumAll, DISPID_STARTENUM, &dispid);
while( hr == S_OK)
{
DISPPARAMS dispParamsNoArgs = {0};

if ( i != 0 )
sm << L", ";

// get key
CComBSTR key;
if ( S_OK != px->GetMemberName( dispid, &key ) )
break;

// get value
CComVariant varItem;
if ( S_OK == px->InvokeEx(dispid, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParamsNoArgs, &varItem, NULL, NULL))
{
sm << (LPCWSTR)key << L":";
ValueVariantToString( sm, varItem );
}

hr = px->GetNextDispID(fdexEnumAll, dispid, &dispid);
i++;
}
sm << L"}";
}
}
else
{
_variant_t vd;
if ( S_OK == ::VariantChangeType( &vd, &v, 0, VT_BSTR ) )
sm << (LPCWSTR)vd.bstrVal;
}
}

JSRTをブログにしている日本人がほとんどいないので、もうこのレイヤーのエンジニアは絶滅危惧種のようだ。
ざっと国内に5人くらいだと思う。