duktape将参数传递给js脚本并获取结果的示例

时间:2018-03-15 22:09:48

标签: duktape

嗨所以我正在看duktape,但我似乎无法找到一个简单的例子,它会做类似的事情:

  • 预编译一些js。
  • 传递js一些输入,例如字符串和数字并运行它。
  • 得到那个js的结果。

看来这里的例子是如何评估js到这里是如何从js调用C函数,也许我错过了它。

好吧,似乎在抨击API文档和反复试验后,我最终得到了类似的内容:

duk_context *ctx = duk_create_heap_default();

duk_eval_string(ctx, "(function helloWorld(a,b) { return a.includes(b); })");    
duk_dump_function(ctx);

int i;
for(i = 0; i < 10; i++) {
  duk_dup_top(ctx); // I don't know why but it seems needed
  duk_load_function(ctx);  /* [ ... bytecode ] -> [ ... function ] */
  duk_push_string(ctx, "the");
  duk_push_string(ctx, "th");
  duk_call(ctx, 2);

  duk_bool_t res = duk_get_boolean(ctx, -1);
  if(res) {
    printf("You got it!\n");
  } else {
    printf("yeah nah!\n");
  }
  duk_pop(ctx);
}

虽然我注意到如果JS有错误我会遇到一个段错误,也许我打算检查一下?

这也是缓存JS的正确方法吗?

1 个答案:

答案 0 :(得分:1)

好的,这是基于我已经开始工作的代码的拼凑在一起的代码段,它应该与您的示例类似

bool compileJS(duk_context *ctx, const char* programBody)
{
    bool success = false;

    // Compile the JS into bytecode
    if (duk_pcompile_string(ctx, 0, programBody) != 0)
    {
        // Error in program code

        printf("Compile failed\n");
        printf("%s\n", duk_safe_to_string(ctx, -1));
    }
    else
    {
        // Actually evaluate it - this will push the compiled code into the global scope
        duk_pcall(ctx, 0);

        success = true;

    }
    duk_pop(ctx);

    return success;
}

duk_bool_t runJSFunction(duk_context *ctx, const char* funcName, const char* arga, const char* argb)
{
    duk_bool_t returnVal;

    // Get a reference to the named JS function
    if (duk_get_global_string(ctx, funcName))
    {
        // Function found, push the args

        duk_push_string(ctx, arga);
        duk_push_string(ctx, argb);

        // Use pcall - this lets you catch and handle any errors
        if (duk_pcall(ctx, 2) != DUK_EXEC_SUCCESS)
        {
            // An error occurred - display a stack trace
            duk_get_prop_string(ctx, -1, "stack");
            printf(duk_safe_to_string(ctx, -1));
        }
        else
        {
            // function executed successfully - get result
            returnVal = duk_get_boolean(ctx, -1);
        }
    }
    else
    {
        printf("JS function not found!\n");
        returnVal = false;
    }

    duk_pop(ctx); // pop result

    return returnVal;
}

void testJS()
{
    duk_context *ctx = duk_create_heap_default();

    const char* programBody = "function helloWorld(a,b) { return a.includes(b); }";

    if (compileJS(ctx, programBody))
    {
        for (int i = 0; i < 10; ++i)
        {
            bool ret = runJSFunction(ctx, "helloWorld", "the", "th");
            if (ret)
            {
                printf("You got it!\n");
            }
            else
            {
                printf("yeah nah!\n");
            }
        }
    }
}

我已将其分为三个函数,因此您可以看到函数的初始化和编译(以及缓存)是如何与JS执行分开处理的。我还添加了基本的错误处理,如果你的JS代码无法编译或运行,它应该显示错误。