我花了很长时间才弄清楚这是如何工作的。当涉及到 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" ]
]);
然后你accessArray()
像这样在 c++ 中注册函数:
//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)
无论您使用 index 0
、堆栈的底部索引还是-1
堆栈的顶部索引来访问外部数组,目前都没有区别。
当你调用 时duk_get_prop_index(dc, 0, outerIndex)
,它会将外部数组的一个元素压入栈顶:
(bottom of stack) [ outer array, inner array ] (top of stack)
现在,index0
指向外部数组,并且 index-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)
也可以看看: