JS调用C函数

1. 使用编译命令就可以将.cpp文件编译为.html文件,并在网页进行运行:

./emcc tests/hello_function.cpp -o function.html -s EXPORTED_FUNCTIONS="['_int_sqrt']"

2. ①编译完,你可以使用JavaScript调用cwrap()拿到int_sqrt函数。继而可以进行其他操作。

    int_sqrt = Module.cwrap('int_sqrt', 'number', ['number'])
    int_sqrt(12)
    int_sqrt(28)

第一个参数是函数名,第二个参数是函数返回类型,第三个是参数类型。
返回类型和参数类型中可以用类型有三个,分别是number,string和array。number(是js中的number,对应着C中的整型,浮点型,一般指针),string(是JavaScript中的string,对应着C中的char,C中char表示一个字符串),array(是js中的数组或类型数组,对应C中的数组;如果是类型数组,必须为Uint8Array或者Int8Array)。

② 使用.cwrap()的注意事项

  • 这些方法用于编译的C函数,对进行过函数名改编的C++函数不工作。
  • 推荐你导出你要用JavaScript调用的函数。

         A. 导出是在编译阶段做的。比如-s EXPORTED_FUNCTIONS='["_main","_other_function"]' 导出了main()和other_function()。

         B. 导出时给函数名加下划线“_”,见A。

         C. A中把main也导出了,如果你不导出main,mian就会变成无效代码,这个导出列表应该是完整 的可以keep alive的函数列表。

         D. Emscripten会做无效代码清除以减小生成的代码体积,所以请确保导出了所有你想用js调的函数。

         E. 如果编译是优化编译-O2级别及以上,会进行代码改编,包括函数名。但是通过-s EXPORTED_FUNCTIONS导出的函数可以继续使用原来的函数名。

         F. 如果你想导出一个js库函数(比如,src/library*.js这样的),除了用EXPORTED_FUNCTIONS ,还得用DEFAULT_LIBRARY_FUNCS_TO_INCLUDE。 * 使用Module.ccall调用,不要直接用ccall。前者在代码进行优化编译时也工作。

3. 在JS中直接调C中的函数,不必使用ccall()或cwrap()

①使用编译命令:

emcc api_example.c -o api_example.js

②可以用以下代码执行这个库中的函数:

var em_module = require('./api_example.js');

em_module._sayHi(); // 方法一:直接调用,函数名前要加_
em_module.ccall("sayHi"); // 方法二:使用ccall或cwrap调用,函数名前不需要加_
发布了38 篇原创文章 · 获赞 2 · 访问量 1526

猜你喜欢

转载自blog.csdn.net/qq_34754747/article/details/104037188