如何通过 emscripten 在 C++ 和 javascript 之间传递字符串
Posted
技术标签:
【中文标题】如何通过 emscripten 在 C++ 和 javascript 之间传递字符串【英文标题】:How to pass strings between C++ and javascript via emscripten 【发布时间】:2014-02-16 21:33:13 【问题描述】:我正在学习 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 中得到垃圾。
所以我的问题很明确:如何通过 Emscripten 在 JS 和 C++ 之间编组字符串类型?
【问题讨论】:
【参考方案1】:extern "C" 无法识别 std::string。
您可能想试试这个: 测试.cpp
#include <emscripten.h>
#include <string.h>
extern "C" int stringLen(char* p)
return strlen(p);
使用以下命令编译cpp代码:
emcc Test.cpp -s EXPORTED_FUNCTIONS="['_stringLen']
示例测试代码: 测试.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>
【讨论】:
这并没有回答完整的问题,即如何在 C++ 代码之间传递字符串。【参考方案2】:如果对函数使用 extern "C",则不能在其签名中使用 C++ 类型。
所以如果你想使用std::string,那么你可以使用“Embind”或“WebIDL Binder”。参考here
我更喜欢 embind,所以这是解决您问题的示例代码。
P.S 我不知道如何在这里通过引用传递变量,所以按值传递。
// 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 时。
有another approach,您可以在其中从 JS 在 C++ 堆上执行 Malloc,然后进行操作,但上述方法应该更容易。
【讨论】:
"如果你在函数中使用 extern "C",你不能在它的签名中使用 C++ 类型。"我看到两个答案都声称这一点,但我认为这不是真的。 AFAIK 这只是防止名称修改的链接规范。我可以编译extern "C" void foo(std::string s) std::cout << "hello, world" << std::endl;
就好了【参考方案3】:
一些想法:
-
我调用方法的唯一方法是使用
crwap
或
ccall
?var length = Module.ccall('stringLen', ['string'], 'number');
您是否在EXPORTED_FUNCTIONS
参数中包含stringLen
和stringTest
?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/
希望对您有所帮助。
【讨论】:
以上是关于如何通过 emscripten 在 C++ 和 javascript 之间传递字符串的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Socket.io 和 emscripten 使用 javascript 库?