Duktape获得数组值

时间:2015-08-05 19:35:07

标签: arrays duktape

我可以在全局范围内按键粘贴数组,如下所示:

duk_push_global_object(ctx); duk_idx_t arr_idx = duk_push_array(ctx); duk_push_string(ctx, "string by key"); duk_put_prop_string(ctx, arr_idx, "key"); duk_put_prop_string(ctx, -2, "global_array"); duk_pop(ctx);

但是我如何能够在以后通过全球的关键获得价值呢?

P.S。:对不起我的英语。

2 个答案:

答案 0 :(得分:1)

您发布的C代码等同于以下Javascript(这是正确的吗?):

var t = [];  // not actually registered into global object
t.key = 'string by key';
global_array = t;

回读 global_array.key

duk_get_global_string(ctx, "global_array");
duk_get_prop_string(ctx, -1, "key");
/* ... use the value, then pop it */
duk_pop(ctx);  /* pop global_array */

顺便说一句,您可以按如下方式简化问题中的代码:

duk_idx_t arr_idx = duk_push_array(ctx);
duk_push_string(ctx, "string by key");
duk_put_prop_string(ctx, arr_idx, "key");
duk_put_global_string(ctx, -2, "global_array");

答案 1 :(得分:0)

我花了很长时间才弄清楚这是如何工作的。当涉及到 Duktape 堆栈索引以及推送和弹出内容时,文档和示例可能会相当混乱。让我尝试以有组织的方式逐个呈现所有内容,并留出额外的间距以帮助使其更清晰。 (这也有助于我巩固自己的理解。)

请注意,在 OP 问题的情况下,您将使用 duk_get_prop_string() 而不是 duk_get_prop_index(),因为他实际上更像是使用对象通过。键->值访问而不是使用索引的数组。


假设您将 JS 数组嵌套在这样的数组中,您想使用任意 C++ accessArray() 函数访问这些数组:

//Javascript, calling a c++ function, passing nested arrays.
accessArray([
  [ "str1", "str2" ],
  //Varying the number of elements.
  [ "str3", "str4", "str5" ]
]);

然后像这样在 C++ 中注册 accessArray() 函数:

//First, push the c++ function onto the Duktape stack.
//Make sure to put the # of arguments accessArray expects; in this case, it's 1.
duk_push_c_function(duktapeContext, accessArray, 1);
//Then, register that c++ function as a global JS ("string") variable,
//to access it like in the above JS.
duk_put_global_string(duktapeContext, "accessArray");

使用该上下文,您可以像这样创建 c++ 函数:

#include <string>

//The format of a duk_c_function.
duk_ret_t accessArray(duk_context* dc)
{
  //Note: You could also first check if the parameter is an array using duk_is_array().
  
  //Determine the number of arguments in the array parameter. In this case, the array is
  //the first parameter, so it will be at the bottom of the function call stack,
  //at index 0.
  duk_size_t outerArraySize = duk_get_length(dc, 0);
  
  //Loop through the outer array.
  for (duk_size_t outerIndex = 0; outerIndex < outerArraySize; ++outerIndex)
  {
    //Get the property at [outerIndex] of the outer array (still) at
    //stack index 0.
    //This function puts the property at the top of the stack, at index -1.
    //We'll pop it later when finished.
    duk_get_prop_index(dc, 0, outerIndex);
    
      //Now it gets a little more complicated. This time, we use the property at the top
      //of the stack, at index -1, which is the inner array.
      //First, we have to get its size.
      //Note that this function merely returns a value; it does not change the stack.
      duk_size_t innerArraySize = duk_get_length(dc, -1);
      
      //Loop through the inner array.
      for (duk_size_t innerIndex = 0; innerIndex < innerArraySize; ++innerIndex)
      {
        //Just like before, we get the property at [innerIndex] of the inner array
        //at index -1.
        //This puts the property at the top of the stack, so we'll need to pop it
        //when finished.
        duk_get_prop_index(dc, -1, innerIndex);
          
          //We know/expect it as a string.
          std::string myString = duk_to_string(dc, -1);
          
        //Pop the inner array's property off the stack; now, the inner array will be
        //back at the top of the stack, at index -1.
        duk_pop(dc);
      }
    
    //Pop the property that we got earlier using duk_get_prop_index(); now, the
    //outer array will be back at the top of the stack, at index -1.
    duk_pop(dc);
  }
  
  return 0;
}

所以,让事情完整循环:当这个 accessArray() 函数被调用时,Duktape 堆栈看起来像这样:

(bottom of stack) [ outer array ] (top of stack)

无论是使用索引0(栈底索引)还是-1(栈顶索引)访问外部数组,目前都没有区别。

当你调用 duk_get_prop_index(dc, 0, outerIndex) 时,它会将外部数组的一个元素压入栈顶:

(bottom of stack) [ outer array, inner array ] (top of stack)

现在,索引 0 指的是外部数组,索引 -1 已更改为访问内部数组。然后,您可以通过访问内部数组的元素。例如duk_get_prop_index(dc, -1, innerIndex),将另一个元素压入栈顶:

(bottom of stack) [ outer array, inner array, inner array element ] (top of stack)

然后使用 duk_to_string(dc, -1) 将该内部数组元素转换为字符串。然后,您可以使用 duk_pop(dc):

弹出内部数组元素
(bottom of stack) [ outer array, inner array ] (top of stack)

并再次使用 duk_pop(dc) 弹出内部数组本身:

(bottom of stack) [ outer array ] (top of stack)

另见: