Я изучаю emscripten, и я даже не могу заставить работать базовые манипуляции со строками при передаче строк между C ++ и JS.
Например, я хотел бы написать функцию длины строки. В C ++:
extern "C" int stringLen(std::string p)
{
return p.length();
}
Вызывается из JavaScript как:
var len = _stringLen("hi.");
Это дает 0
для меня. Как мне сделать эту работу, как ожидалось? Какой тип строки мне следует использовать здесь? char const*
? std::wstring
? std::string
? Никто, кажется, не работает; Я всегда получаю довольно случайные значения.
Это только начало … Как мне тогда вернуть строка из C ++, как это?
extern "C" char *stringTest()
{
return "...";
}
И в JS:
var str = _stringTest();
Опять же, я не могу найти способ заставить эту работу; Я всегда получаю мусор в JS.
Таким образом, мой вопрос однозначен: как мне маршалировать строковые типы между JS и C ++ через Emscripten?
extern «C» не распознает std :: string.
Вы можете попробовать это:
test.cpp
#include <emscripten.h>
#include <string.h>
extern "C" int stringLen(char* p)
{
return strlen(p);
}
Используйте следующую команду для компиляции кода cpp:
emcc Test.cpp -s EXPORTED_FUNCTIONS="['_stringLen']
Пример тестового кода:
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hello World !</title>
<script src="a.out.js"></script>
<script>
var strLenFunction = Module.cwrap('stringLen', 'number', ['string']);
var len1 = strLenFunction("hi."); // alerts 3
alert(len1);
var len2 = strLenFunction("Hello World"); // alerts 11
alert(len2);
</script>
</head>
</html>
Если вы используете extern «C» с функцией, вы не можете использовать типы C ++ в ее сигнатуре.
Так что если вы хотите использовать std :: string, то вы можете использовать «Embind» или «WebIDL Binder». обращаться Вот
Я предпочитаю embind, так что это пример кода для вашей проблемы.
П.С .: Я не уверен, как передавать переменные по ссылке, поэтому делаю это по значению.
// This is your routine C++ code
size_t MyStrLen(std::string inStr) {
return inStr.length();
}
// This is the extra code you need to write to expose your function to JS
EMSCRIPTEN_BINDINGS(my_module) {
function("MyStrLen", &MyStrLen);
}
Теперь в JS все, что вам нужно сделать, это:
var myStr = "TestString";
Module.MyStrLen(myStr);
Убедитесь, что вы передаете флаг
—привязывать
при вызове emcc.
Есть другой подход где вы можете сделать Malloc в куче C ++ из JS, а затем выполнить манипуляции, но описанный выше подход должен быть проще.
Несколько мыслей:
crwap
или жеccall
?var length = Module.ccall('stringLen', ['string'], 'number');
stringLen
а также stringTest
в вашем EXPORTED_FUNCTIONS
параметр?emcc hello_world.cpp ... -s EXPORTED_FUNCTIONS=['_stringLen','_stringTest']
Посмотрите здесь для более подробной информации:
http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html
Или мой учебник hello_world:
http://www.brightdigit.com/hello-emscripten/
Надеюсь, это поможет.