2017-07-11 53 views
0

好吧,所以基本上我有一个很长的数组对象,我需要多次调用一个JavaScript函数,并将该数组作为参数。每当我调用函数时重新创建列表时,我已经知道它的工作原理,但是试图将数组移动到Duktape堆栈的顶部并不像预期的那样工作。也许我是完全错误的轨道上......执行两次函数

duk_context* ctx(duk_create_heap_default()); 

duk_push_c_function(ctx, nativePrint, DUK_VARARGS); 
duk_put_global_string(ctx, "print"); 

/// Define the function the first time 
duk_eval_string(ctx, "function func(entries, targetEntry) { print(targetEntry, JSON.stringify(entries)); return 404; }"); 
duk_get_global_string(ctx, "func"); 

/// Define lambdas to create the array 
auto pushObject = [&]() { 
    duk_idx_t obj_idx; 

    obj_idx = duk_push_object(ctx); 
    duk_push_int(ctx, 42); 
    duk_put_prop_string(ctx, obj_idx, "meaningOfLife"); 
}; 

auto pushArray = [&]() { 
    duk_idx_t arr_idx; 

    arr_idx = duk_push_array(ctx); 
    pushObject(); 
    duk_put_prop_index(ctx, arr_idx, 0); 
    pushObject(); 
    duk_put_prop_index(ctx, arr_idx, 1); 

    return arr_idx; 
}; 

/// Push the arguments 
auto arr_idx = pushArray(); 
duk_push_number(ctx, 102); 

/// Define lambda to call the function 
auto processEntry = [&]() { 
    if (duk_pcall(ctx, 2 /*nargs*/) != 0) { 
     printf("Error: %s\n", duk_safe_to_string(ctx, -1)); 
    } else { 
     if (duk_is_number(ctx, -1)) cout << "NumRes: " << duk_get_number(ctx, -1) << endl; 
     else printf("Res: %s\n", duk_safe_to_string(ctx, -1)); 
    } 

    duk_pop(ctx); 

    cout << endl; 
}; 

/// Calling the function the first time 
processEntry(); 

/// Loading the function as the global string again 
duk_eval_string(ctx, "function func(entries, targetEntry) { print(targetEntry, JSON.stringify(entries)); return 404; }"); 
duk_get_global_string(ctx, "func"); 

/// Attempt to move the array to the top and execute the function 
/// Executing pushArray(); again works but not duk_swap_top(...); 
// pushArray(); 
duk_swap_top(ctx, arr_idx); 
duk_push_number(ctx, 444); 
processEntry(); 

正如你所看到的,在最底层我尝试调用duk_swap_top(ctx, arr_idx)以阵列移动到顶部。显然,它不会做我认为会的,而是返回TypeError: undefined not callable。当用另一个pushArray();代替它时,它按预期工作,并且和被打印输出。

回答

0

在我看来,你推一个数组和“102”的值栈:

[ ... array 102 ] 

你然后调用duk_pcall()消耗的参数(NARGS = 2),并推动结果:

[ ... result ] 

然后弹出结果。调用之后,数组不再处于值栈中。

有各种不同的方式来组织你的代码,但是你可以先注册“功能”和创建数组,然后用在每次调用下面的序列(包括第一):

duk_get_global_string(ctx, "func"); 
duk_dup(ctx, arr_idx); /* duplicate array reference */ 
duk_push_uint(ctx, 1234); /* additional argument, varies? */ 
rc = duk_pcall(ctx, 2); 
/* inspect result */ 
duk_pop(ctx); 

这蜜饯调用之间的arr_idx数组。