--- title: C + QuickJS pagination_prev: demos/bigdata/index pagination_next: solutions/input --- import current from '/version.js'; QuickJS is an embeddable JS engine written in C. It provides a separate set of functions for interacting with the filesystem and the global object. It can run the standalone browser scripts. The [Standalone scripts](/docs/getting-started/installation/standalone) can be parsed and evaluated in a QuickJS context. ## Integration Details _Initialize QuickJS_ QuickJS provides a `global` object through `JS_GetGlobalObject`: ```c /* initialize */ JSRuntime *rt = JS_NewRuntime(); JSContext *ctx = JS_NewContext(rt); /* obtain reference to global object */ JSValue global = JS_GetGlobalObject(ctx); /* DO WORK HERE */ /* free after use */ JS_FreeValue(ctx, global); /* cleanup */ JS_FreeContext(ctx); JS_FreeRuntime(rt); ``` :::warning All values must be freed with `JS_FreeValue` before calling `JS_FreeContext`! `JS_IsException` should be used for validation. 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 QuickJS context: ```c 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); fsee (f, 0, SEEK_SET); } char *buf = (char *)malloc(fsize * sizeof(char)); *sz = fread((void *) buf, 1, fsize, f); fclose(f); return buf; } // ... /* load library */ { size_t len; char *buf = read_file("xlsx.full.min.js", &len); JS_Eval(ctx, buf, len, "", 0); free(buf); } ``` To confirm the library is loaded, `XLSX.version` can be inspected: ```c /* obtain reference to the XLSX object */ JSValue XLSX = JS_GetPropertyStr(ctx, global, "XLSX"); /* print version */ JSValue version = JS_GetPropertyStr(ctx, XLSX, "version"); size_t vlen; const char *vers = JS_ToCStringLen(ctx, &vlen, version); printf("Version: %s\n", vers); ``` ### Reading Files `JS_NewArrayBuffer` can generate an `ArrayBuffer` from a C byte array. The function signature expects `uint8_t *` instead of `char *`: ```c /* read file */ size_t dlen; uint8_t * dbuf = (uint8_t *)read_file("pres.numbers", &dlen); /* load data into array buffer */ JSValue ab = JS_NewArrayBuffer(ctx, dbuf, dlen, NULL, NULL, 0); /* obtain reference to the XLSX object */ JSValue XLSX = JS_GetPropertyStr(ctx, global, "XLSX"); /* call XLSX.read(ab) */ JSValue XLSX_read = JS_GetPropertyStr(ctx, XLSX, "read"); JSValue args[] = { ab }; JSValue wb = JS_Call(ctx, XLSX_read, XLSX, 1, args); ``` ## Complete Example The "Integration Example" covers a traditional integration in a C application, while the "CLI Test" demonstrates other concepts using the `quickjs` CLI tool. ### Integration Example :::note This demo was last tested on 2023 March 11 against QuickJS commit `2788d71` 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 `libquickjs.a`: ```bash git clone https://github.com/bellard/quickjs cd quickjs git checkout 2788d71 make cd .. ``` 1) Copy `libquickjs.a` and `quickjs.h` into the working directory: ```bash cp quickjs/libquickjs.a . cp quickjs/quickjs.h . ``` 2) Download [`sheetjs.quick.c`](pathname:///quickjs/sheetjs.quick.c): ```bash curl -LO https://docs.sheetjs.com/quickjs/sheetjs.quick.c ``` 3) Build the sample application: ```bash gcc -o sheetjs.quick -Wall -lm libquickjs.a sheetjs.quick.c ``` This program tries to parse the file specified by the first argument 4) Download the standalone script and test file:
{`\
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
curl -LO https://sheetjs.com/pres.numbers`}
5) Run the test program:
```
./sheetjs.quick pres.numbers
```
If successful, the program will print the library version number, file size,
first worksheet name, and the contents of the first sheet as CSV rows.
### CLI Test
:::note
This demo was last tested on 2023 March 11 against QuickJS `2021-03-27`.
:::
0) Ensure `quickjs` command line utility is installed
1) Download the standalone script and the test file:
{`\
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
curl -LO https://sheetjs.com/pres.numbers`}
2) Download [`SheetJSQuick.js`](pathname:///quickjs/SheetJSQuick.js)
```bash
curl -LO https://docs.sheetjs.com/quickjs/SheetJSQuick.js
```
3) Test the program:
```bash
quickjs SheetJSQuick.js
```
If successful, the script will generate `SheetJSQuick.xlsx`.