首页 > 解决方案 > EM_JS:如何将 int argc、char **argv 转换为 JS 字符串数组?

问题描述

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

这是我的示例代码:

主.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);
}

索引.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 字符串数组?

标签: javascriptc++cwebassemblyemscripten

解决方案


如何正确转换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;
}

因此,您可以像这样HEAP32使用UTF8ToString

主程序

#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' ]

推荐阅读