--- title: C++ + ChakraCore pagination_prev: demos/bigdata/index pagination_next: solutions/input --- import current from '/version.js'; import CodeBlock from '@theme/CodeBlock'; ChakraCore is an embeddable JS engine written in C++. The [Standalone scripts](/docs/getting-started/installation/standalone) can be parsed and evaluated in a ChakraCore context. ## Integration Details _Initialize ChakraCore_ ChakraCore provides a `global` object through `JsGetGlobalObject`: ```cpp /* initialize */ JsRuntimeHandle runtime; JsContextRef context; size_t cookie = 0; JsCreateRuntime(JsRuntimeAttributeNone, nullptr, &runtime); JsCreateContext(runtime, &context); JsSetCurrentContext(context); /* obtain reference to global object */ JsValueRef global; JsGetGlobalObject(&global); /* DO WORK HERE */ /* cleanup */ JsSetCurrentContext(JS_INVALID_REFERENCE); JsDisposeRuntime(runtime); ``` :::note Cleanup and validation code is omitted from the discussion. The integration example shows structured validation and controlled memory usage. ::: _Load SheetJS Scripts_ The main library can be loaded by reading the script from the file system and evaluating in the ChakraCore context: ```cpp static char *read_file(const char *filename, size_t *sz) { FILE *f = fopen(filename, "rb"); if(!f) return NULL; long fsize; { fseek(f, 0, SEEK_END); fsize = ftell(f); fseek(f, 0, SEEK_SET); } char *buf = (char *)malloc(fsize * sizeof(char)); *sz = fread((void *) buf, 1, fsize, f); fclose(f); return buf; } #define EVAL_FILE(path) {\ JsValueRef filename; \ JsValueRef result; \ JsCreateString(path, strlen(path), &filename); \ size_t len; const char* script = read_file(path, &len);\ JsValueRef src;\ JsCreateExternalArrayBuffer((void*)script, len, nullptr, nullptr, &src);\ JsRun(src, cookie++, filename, JsParseScriptAttributeNone, &result); \ } // ... /* load library */ EVAL_FILE("shim.min.js") EVAL_FILE("xlsx.full.min.js") ``` ### Reading Files `JsCreateExternalArrayBuffer` can generate an `ArrayBuffer` from a C byte array: ```cpp /* read file */ size_t len; char *buf = read_file(argv[1], &len); /* load data into array buffer */ JsValueRef ab; JsCreateExternalArrayBuffer((void*)buf, len, nullptr, nullptr, &ab); ``` After pushing the data, it is easiest to store properties on `globalThis`: ```cpp /* assign to the `buf` global variable */ JsValueRef buf_str; JsCreateString("buf", strlen("buf"), &buf_str); JsObjectSetProperty(global, buf_str, ab, true); /* call globalThis.wb = XLSX.read(ab) */ const char* script_str ="globalThis.wb = XLSX.read(buf);" JsValueRef script; JsCreateExternalArrayBuffer((void*)script_str, (size_t)strlen(script_str), nullptr, nullptr, &script); JsRun(script, cookie++, fname, JsParseScriptAttributeNone, &result); ``` ## Complete Example The "Integration Example" covers a traditional integration in a C application, while the "CLI Test" demonstrates other concepts using the `ch` CLI tool. ### Integration Example :::note This demo was last tested on 2023 April 09 against ChakraCore commit `c3ead3f` on a Intel Mac. `gcc -v` printed: ``` Apple clang version 14.0.0 (clang-1400.0.29.202) Target: x86_64-apple-darwin21.6.0 ``` ::: 0) Build ChakraCore: ```bash git clone https://github.com/Microsoft/ChakraCore cd ChakraCore git checkout c3ead3f ./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 cd .. ``` 1) Download the source file and `Makefile`: - [`sheetjs.ch.cpp`](pathname:///chakra/sheetjs.ch.cpp) - [`Makefile`](pathname:///chakra/Makefile) ```bash curl -LO https://docs.sheetjs.com/chakra/sheetjs.ch.c curl -LO https://docs.sheetjs.com/chakra/Makefile ``` 2) Build the sample application: ```bash make ``` This program tries to parse the file specified by the first argument 4) Download the standalone script, shim script, and test file: