For the sake of this introductory post, I am going to show you how to implement a simple printf-like functionality with Chakra (please note that I am going to provide just an overview, for more details see ). Suppose we want to implement a very simple print function that accepts some format string, an integer and a string and formats the output as shown.
native.printf('number=%#x string=%s\n', 255, 'test')
We are going to embed Chakra engine in a simple console app that runs this script and just outputs the result.
[Note: for the sake of brevity I am going to omit the error handling. The source code contains all the error checks though.]
JsCreateRuntime(JsRuntimeAttributeNone, JsRuntimeVersion11, nullptr, &runtime);
Once we have created a runtime we have to create an execution context. There can be multiple execution contexts that are active on a thread at the same time.
JsCreateContext(runtime, nullptr, &context);
Now, it is time to execute the script. This is done via
wstring script(L"native.printf('number=%#x string=%s\\n', 255, 'test')");
JsSourceContext contextCookie = 0;
JsRunScript(script.c_str(), contextCookie, L"source", &result);
Right now, you are probably guessing where this
native.prinft thing would come from. That’s right, I missed that part on purpose because I want to show the very basic workflow:
- create a runtime
- create a context
- run the script
Let’s see what is needed to make
native property on the global object. Then we have to create another object, actually a function, and make it accessible through
printf property on the
JsCreateFunction(PrintFormat, nullptr, &printfFunc);
JsSetProperty(nativeObj, printfProp, printfFunc, true);
JsSetProperty(global, nativeProp, nativeObj, true);
The final missing thing is the
PrintFormat callback function.
JsValueRef CALLBACK PrintFormat(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
const wchar_t *format;
JsStringToPointer(arguments, &format, &length);
const wchar_t *str;
JsStringToPointer(arguments, &str, &length);
wprintf(format, variant.intVal, str);
That’s all. We implemented all the functionality required to execute
In closing I would say that using Chakra engine is fairly easy. The API is not object-oriented and some less experienced developers may find it as a drawback. On the other hand it is easy the incorporate Chakra C-style API in existing OO code base or use it from a script language like Python.
Download source code