Как передать строки между C ++ и JavaScript через emscripten

Я изучаю 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?

5

Решение

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>
8

Другие решения

Если вы используете 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, а затем выполнить манипуляции, но описанный выше подход должен быть проще.

2

Несколько мыслей:

  1. Единственный способ, которым я вызвал метод — это использование crwap или же
    ccall?
    var length = Module.ccall('stringLen', ['string'], 'number');
  2. Вы в том числе 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/

Надеюсь, это поможет.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector