2022年6月16日 星期四

C開發筆記 - 使用 JS Engine : Duktape 接收與傳遞 Javascript Object

對嵌入式設備來說,如果資源夠大的話,直接用 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");

更多完整資訊,請參考:github.com/changyy/study-duktape

沒有留言:

張貼留言