【问题标题】:EM_JS: How to convert int argc, char **argv to a JS array of strings?EM_JS:如何将 int argc、char **argv 转换为 JS 字符串数组?
【发布时间】:2020-08-09 00:26:12
【问题描述】:

我正在尝试从 C/C++ 调用 JS 函数,并将字符串数组作为参数。

这是我的示例代码:

ma​​in.c:

#include <stdio.h>
#include <emscripten.h>

EM_JS(void, call_myFunc, (int argc, char **argv), {
     
    var arr = [];
    for (let i = 0; i < argc; i++) {
      arr.push(UTF8ToString(argv[i]));
    }
    myFunc(arr);
});

int main()
{
    int argc = 4;
    char *argv[5] = { "ab", "cd", "ef", "gh" };
    call_myFunc(argc, argv);
}

index.html:

<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <script>
  function myFunc(args) {
    console.log(args);
  }
  </script>
  <script async src="main.js"></script>
</body>

</html>

构建:

emcc main.c -o main.html

我得到的结果:

["", "", "", ""]

我想要的结果:

["ab", "cd", "ef", "gh"]

如何正确地将char **argv 转换为 JS 字符串数组?

【问题讨论】:

  • 我很好奇——我们可以把C++代码编译成JS吗?这是什么?
  • 查看 main.html 脚本如何调用并在 index.html 中执行相同操作。至少没有使用 main.wasm。

标签: javascript c++ c webassembly emscripten


【解决方案1】:

如何正确地将char **argv 转换为 JS 字符串数组?

来自emscripten.h的文档:

Null 终止的 C 字符串也可以传递给 EM_JS 函数,但要对它们进行操作,需要将它们从堆中复制出来以转换为高级 JavaScript 字符串。

EM_JS(void, say_hello, (const char* str), {
  console.log('hello ' + UTF8ToString(str));
}

以同样的方式,指向任何类型(包括void *)的指针都可以在EM_JS 代码中传递,它们在其中显示为整数,就像上面的char * 指针所做的那样。可以通过直接读取堆来管理访问数据。

EM_JS(void, read_data, (int* data), {
  console.log('Data: ' + HEAP32[data>>2] + ', ' + HEAP32[(data+4)>>2]);
});

int main() {
  int arr[2] = { 30, 45 };
  read_data(arr);
  return 0;
}

所以,您可以像这样使用HEAP32UTF8ToString

ma​​in.c

#include <stdio.h>
#include <emscripten.h>

EM_JS(void, call_myFunc, (const int argc, const char** argv), {
    var arr = [];
    for (let i = 0; i < argc; i++) {
        const mem = HEAP32[(argv + (i * 4)) >> 2];
        const str = UTF8ToString(mem);
        arr.push(str);
    }
    console.log(arr);
});

int main() {
    const int argc = 4;
    const char* argv[] = { "ab", "cd", "ef", "gh" };
    call_myFunc(argc, argv);
    return 0;
}

编译:

emcc main.c -o main.html

使用node 运行:

node main.js

输出:

[ 'ab', 'cd', 'ef', 'gh' ]

【讨论】:

  • 谢谢!我可以用这个代替吗? EM_JS(void, call_myFunc, (int argc, char **argv), { var arr = []; for (let i = 0; i &lt; argc; i++) { arr.push(UTF8ToString(HEAP32[(argv &gt;&gt; 2) + i])); } myFunc(arr); });
  • @ZackLee:不客气!当然,您可以组合这些语句。只要确保在堆中移动时相应地调整指针,即HEAP32[(argv + (i * 4)) &gt;&gt; 2]。所以,应该是arr.push(UTF8ToString(HEAP32[(argv + (i * 4)) &gt;&gt; 2]));
  • @ZackLee:顺便说一句,你如何测试你现有的设置?你能分享一下吗?
  • @ZackLee:这取决于我相信的方法。我坚信,实际测量所揭示的不仅仅是猜测。以下是相关文章:emscripten.org/docs/porting/connecting_cpp_and_javascript/…
  • 我完全看不懂HEAP32[(argv + (i * 4)) &gt;&gt; 2]这个说法。为什么它乘以 4 并右移 2?有人可以解释吗?谢谢。
猜你喜欢
  • 2014-05-17
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
  • 2014-10-09
  • 2013-09-08
  • 2014-01-10
  • 2016-08-13
相关资源
最近更新 更多