In a wrapper to interface the V8 JavaScript engine with C++ code, I'd like to call a C++ function passing it an object by value. The object is automatically constructed from data inside JavaScript.
The C++ function to call takes an object of type T and a template is used to generate an adapter function A, returning T by value. The problem is that the adapter function A needs to call a JavaScript function passing it another C++ function B as a callback. The object of type T is constructed in that function B. It cannot be returned back to A through JavaScript, which doesn't know how to handle the object of type T.
The simplest way is to have a local variable of type T inside function A. A pointer to it is given to B, which assigns a new value to the local variable, which A later returns, approximately like so (some details omitted regarding how arguments are passed to callJavaScript and callback):
C++ code:
T A() {
T data;
callJavaScript(someJavaScriptFunction, &B, &data);
return data;
}
void B(T *data, int importantValue) {
*data = T(importantValue);
}
JavaScript code:
function someJavaScriptFunction(callback, dataRef) {
callback(dataRef, getImportantValueSomehow());
}
But what if the type T doesn't support assignment or even have a copy constructor? Is there a way to avoid unnecessary copying? I thought of allocating empty space inside function A as a local variable:
typename std::aligned_storage<sizeof(T), alignof(T)>::type data;
Function B could then construct the object in that space using placement new, but how can I return the resulting object from A using move semantics? How to call a possible destructor correctly?
My final idea was to use more template trickery to allocate space for parameters for type T's constructor inside function A, set them through pointers from B and finally construct the object inside A, but it will get nasty if data in some parameters goes out of scope when callJavaScript returns. Is there a solution for that?
Aucun commentaire:
Enregistrer un commentaire