Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
构造一个对象在别处按值返回 在V8 JavaScript引擎与C++代码接口的包装器中,我想调用一个C++函数,它通过值传递一个对象。该对象是根据JavaScript中的数据自动构造的 调用C++函数取T类对象,模板用于生成适配器函数A,按值返回T。问题是适配器函数A需要调用JavaScript函数,将它传递给另一个C++函数B作为回调。类型为T的对象是在函数B中构造的。它不能通过JavaScript返回给A,因为JavaScript不知道如何处理类型为T的对象_C++_Node.js_C++11_V8 - Fatal编程技术网

构造一个对象在别处按值返回 在V8 JavaScript引擎与C++代码接口的包装器中,我想调用一个C++函数,它通过值传递一个对象。该对象是根据JavaScript中的数据自动构造的 调用C++函数取T类对象,模板用于生成适配器函数A,按值返回T。问题是适配器函数A需要调用JavaScript函数,将它传递给另一个C++函数B作为回调。类型为T的对象是在函数B中构造的。它不能通过JavaScript返回给A,因为JavaScript不知道如何处理类型为T的对象

构造一个对象在别处按值返回 在V8 JavaScript引擎与C++代码接口的包装器中,我想调用一个C++函数,它通过值传递一个对象。该对象是根据JavaScript中的数据自动构造的 调用C++函数取T类对象,模板用于生成适配器函数A,按值返回T。问题是适配器函数A需要调用JavaScript函数,将它传递给另一个C++函数B作为回调。类型为T的对象是在函数B中构造的。它不能通过JavaScript返回给A,因为JavaScript不知道如何处理类型为T的对象,c++,node.js,c++11,v8,C++,Node.js,C++11,V8,最简单的方法是在函数a中有一个T类型的局部变量。指向它的指针被赋予B,B给局部变量分配一个新值,a随后返回,大致如此(省略了有关如何将参数传递给callJavaScript和callback的一些细节。实际上,T的构造函数和B函数可能会将任意数量的更复杂类型作为参数): C++代码: T A() { T data; callJavaScript("someJavaScriptFunction", &B, &data); return data; }

最简单的方法是在函数a中有一个T类型的局部变量。指向它的指针被赋予B,B给局部变量分配一个新值,a随后返回,大致如此(省略了有关如何将参数传递给callJavaScript和callback的一些细节。实际上,T的构造函数和B函数可能会将任意数量的更复杂类型作为参数):

C++代码:

T A() {
    T data;

    callJavaScript("someJavaScriptFunction", &B, &data);

    return data;
}

void B(T *data, int importantValue) {
    *data = T(importantValue);
}
JavaScript代码:

function someJavaScriptFunction(callback, dataRef) {
    callback(dataRef, getImportantValueSomehow());
}
但是,如果类型T不支持赋值,甚至没有复制构造函数,该怎么办?有没有办法避免不必要的复制?我想在函数a中分配一个空空间作为局部变量:

typename std::aligned_storage<sizeof(T), alignof(T)>::type data;
typename std::aligned_storage::type data;
然后,函数B可以使用placement new在该空间中构造对象,但是如何使用move语义从A返回结果对象?如何正确调用可能的析构函数

我的最终想法是使用更多的模板技巧为函数A中类型T的构造函数分配参数空间,通过B中的指针进行设置,最后在A中构造对象,但如果调用JavaScript返回时某些参数中的数据超出范围,会变得很糟糕。有解决方案吗

编辑:这一切的要点是把JavaScript对象的内容变成C++。从C++中读取对象的属性需要用字符串来查找它们。然后,它可以调用具有各种参数的C++回调,这些参数相当快,可以将JavaScript值句柄转换成C++类型。 编辑2:第一个简单的想法是:

typename std::aligned_storage<sizeof(T), alignof(T)>::type data;
::new(&data) T(); // THIS LINE ACTUALLY PLACED IN ANOTHER FUNCTION
return(*reinterpret_cast<T *>(&data));
typename std::aligned_storage::type data;
::new(&data)T();//此行实际放在另一个函数中
返回(*重新解释铸件和数据));

但我是否应该为数据中构造的对象T调用析构函数,何时调用,如何调用?这是一个库,向返回值的接收者添加代码并不是一个真正的选项。

我不确定我是否完全理解了您的问题,但您似乎不需要在函数中传递输出参数

简单地让函数A返回一个值,正如您在问题中所说的那样,让函数B返回一个值

由于“命名返回值优化”,因此不需要赋值运算符或复制构造函数。也就是说,如果您的代码满足“NRVO”的要求,您就可以:

T B(int importantValue) { return T{importantValue}; }
不需要赋值运算符,也不需要从T复制构造函数。 然后,将callJavascript更改为不需要输出参数,但返回一个值,这样就可以在没有复制构造函数或赋值运算符的情况下工作:

T A() { A rv{callJavascript(&B)}; return rv; }
一般来说,使函数不需要输出参数,否则您需要类型具有复制构造函数和赋值运算符,或者违反类型系统


顺便说一句,使
callJavascript
成为一个以可调用为参数的模板。

我不确定我是否完全理解了您的问题,但您似乎不需要在函数中传递输出参数

简单地让函数A返回一个值,正如您在问题中所说的那样,让函数B返回一个值

由于“命名返回值优化”,因此不需要赋值运算符或复制构造函数。也就是说,如果您的代码满足“NRVO”的要求,您就可以:

T B(int importantValue) { return T{importantValue}; }
不需要赋值运算符,也不需要从T复制构造函数。 然后,将callJavascript更改为不需要输出参数,但返回一个值,这样就可以在没有复制构造函数或赋值运算符的情况下工作:

T A() { A rv{callJavascript(&B)}; return rv; }
一般来说,使函数不需要输出参数,否则您需要类型具有复制构造函数和赋值运算符,或者违反类型系统


顺便说一句,让
callJavascript
成为一个以可调用为参数的模板。

我最终在a周围使用了一个包装器来处理调用placement new和a的析构函数。它允许库的用户提供任何类a,只要它有一个移动构造函数。关于它出现在一个更新的、更完善的问题及其公认的答案中。

我最终在a周围使用了一个包装器来处理调用placement new和a的析构函数。它允许库的用户提供任何类a,只要它有一个移动构造函数。一个工作测试的完整代码和关于它的讨论可以在更新的bette中找到r制定了问题及其公认的答案。

问题是B的返回值进入V8 JavaScript引擎,并最终通过someJavaScriptFunction返回给A。暂时将该值包装到可存储在JS变量中的句柄中有点浪费。您能捕获JavaScript返回值吗?如果可以的话B的唯一目的似乎是捕获
GetImportantValue
以某种方式产生的整数。如果无法捕获任何任意类型的值,则使用此技术捕获整数的值并从EXPLL调用B