對嵌入式設備來說,如果資源夠大的話,直接用 Node.js 絕對是個不錯方案,受限於硬體資源限制,採用了 Duktape JS Engine。
寫 C Code 操作 Duktape JS Engine 時,呼叫的方式還滿像以前學生時代寫組語的感覺,要先一步步把參數先配置好,接著在呼叫函示去運算。這次就筆記一下,如何從 JS Code 傳遞 Object 到 C Code,以及 C Code 要怎樣傳遞 Object 回 JS Code。
從 JS Code 傳遞 Object 到 C Code:
//
// _js_helper_fetch_url_more 是從 C Code 植入 function,並且接送一個 JS Object,有 url 跟 request_header 兩個屬性
//
if (typeof _js_helper_fetch_url_more !== "undefined") {
var ret = _js_helper_fetch_url_more({
url: 'https://ipinfo.io/country',
request_header: [
'Content-Type: HelloWorld',
'X-MAN: HelloWorld',
],
});
console.log(JSON.stringify(ret));
}
在 C Code 要取得傳進來的 JS Object,並存取 url 跟 request_header 兩個屬性:
if (duk_is_object(ctx, -1) && duk_has_prop_string(ctx, -1, "url")) {
duk_get_prop_string(ctx, -1, "url");
const char *url = duk_to_string(ctx, -1);
duk_pop(ctx);
}
if (duk_has_prop_string(ctx, -1, "request_header")) {
duk_get_prop_string(ctx, -1, "request_header");
if (duk_is_object(ctx, -1) && duk_has_prop_string(ctx, -1, "length")) {
duk_get_prop_string(ctx, -1, "length");
int header_length = duk_get_int(ctx, -1);
printf("#JS_Helper_Fetch_Url_More> access input_object.request_header.length: %d\n", header_length);
duk_pop(ctx);
for (int i=0 ; i<header_length ; ++i) {
duk_get_prop_index(ctx, -1, i);
const char *header_value = duk_get_string(ctx, -1);
printf("#JS_Helper_Fetch_Url_More> access input_object.request_header[%d] = [%s]\n", i, header_value);
duk_pop(ctx);
}
}
duk_pop(ctx);
}
最後,想要從 C Code 傳遞一個 JS Object 回去的方式:
//
// 傳回 {"status": true, "errorCode": 0}
//
duk_idx_t obj_idx;
obj_idx = duk_push_object(ctx);
int errorCode = 0;
duk_push_int(ctx, errorCode);
duk_put_prop_string(ctx, obj_idx, "error_code");
if (errorCode == 0) {
duk_push_true(ctx);
} else {
duk_push_false(ctx);
}
duk_put_prop_string(ctx, obj_idx, "status");