Emscripten's Emplend Mechanism , похоже, обладает довольно хорошей поддержкой для преобразования нативных строк JavaScript в C ++ STD :: String автоматически; Тем не менее, библиотека C ++, которую я пытаюсь создать привязки JavaScript, имеет свой собственный класс строк, который он использует вместо std :: string . За исключением переписывания библиотеки C ++ для использования std :: string , есть ли какой -нибудь способ придать преобразовать строки JavaScript в класс индивидуальной строки этой библиотеки, так же, как он обрабатывает преобразования в/из Std :: string ?
Я думаю, что это должно быть возможно, объявив соответствующий шаблонный структуру BindingType , который содержит необходимый код преобразования, но я Никакой не повезло, чтобы он работал. Когда я загружаю страницу index.html , Safari дает мне ошибку безрассудного отказа обещания: BindingError: не может пройти «ABC» как courviveExamplestring . Вместо этого я хотел бы видеть, что оно печатает xxx abc на консоли JavaScript.
#include
#include
#include
#include
namespace SomeLibrary {
/** Some library's own String class, oversimplified here for illustration purposes only */
class ContrivedExampleString
{
public:
ContrivedExampleString() : _str(NULL) {/* empty */}
ContrivedExampleString(const char * s) : _str(strdup(s)) {/* empty */}
ContrivedExampleString(const ContrivedExampleString & rhs) : _str(NULL) {*this = rhs;}
~ContrivedExampleString() {if (_str) free(_str);}
ContrivedExampleString & operator = (const ContrivedExampleString & rhs)
{
if (&rhs != this)
{
if (_str) free(_str);
_str = rhs._str ? strdup(rhs._str) : NULL;
}
return *this;
}
const char * CStr() const {return _str ? _str : "";}
size_t Length() const {return _str ? strlen(_str) : 0;}
private:
char * _str;
};
/** Contrived example class */
class ContrivedExampleClass
{
public:
ContrivedExampleClass() {/* empty */}
ContrivedExampleString ContrivedExampleFunction(const ContrivedExampleString & s) const
{
return s;
}
};
}; // end SomeLibrary namespace
using namespace emscripten;
using namespace SomeLibrary;
// Tell embind how to autoconvert ContrivedExampleString JavaScript string
template struct emscripten::internal::BindingType
{
typedef struct
{
size_t length;
char data[]; // trailing data
} * WireType;
static WireType toWireType(const std::string & v, rvp::default_tag)
{
WireType wt = (WireType) malloc(sizeof(size_t) + v.length() +1);
wt->length = v.length();
memcpy(wt->data, v.c_str(), v.length()+1);
return wt;
}
static WireType toWireType(const ContrivedExampleString & v, rvp::default_tag)
{
WireType wt = (WireType) malloc(sizeof(size_t) + v.Length() +1);
wt->length = v.Length();
memcpy(wt->data, v.CStr(), v.Length()+1);
return wt;
}
static ContrivedExampleString fromWireType(WireType v) {
//return std::string(v->data, v->length);
return ContrivedExampleString(v->data);
}
};
EMSCRIPTEN_BINDINGS(ContrivedExampleClass) {
class_("ContrivedExampleClass")
.constructor()
.function("ContrivedExampleFunction", &ContrivedExampleClass::ContrivedExampleFunction);
}
< /code>
fwiw i Скомпилируйте приведенный выше код с этой командой: emcc hello.cpp -o hello.js -sexported_runtime_methods = ccall, cwrap -smodularize = 1 -sexport_es6 = 1 -senvironment = web -lembind -lwebsocket.js
... и вот Соответствующий index.html код, который я использую для проверки передачи и возврата строки JavaScript в curvivenExampleclass :: curvivenExamplefunction (const curivenExamplestring &) :
Hello Emscripten
Emscripten C++ to JavaScript
import createModule from "./hello.js";
createModule().then((Module) => {
const ContrivedExampleClass = Module.ContrivedExampleClass;
const cec = new ContrivedExampleClass;
var s = cec.ContrivedExampleFunction("ABC")
console.log("XXX ", s); // should print "XXX ABC"
});
Подробнее здесь: https://stackoverflow.com/questions/794 ... -stdstring