提示:导出前需要先定义导出宏EM_PORT_API,用来更方便的导出和使用:
一、定义EM_PORT_API导出宏
导出前需要先定义导出宏EM_PORT_API,用来更方便的导出和使用
1.创建EM_PORT_API
定义EM_PORT_API宏如下:
#ifndef EM_PORT_API
# if defined(__EMSCRIPTEN__)
# include <emscripten.h>
# if defined(__cplusplus)
# define EM_PORT_API(rettype) extern "C" rettype EMSCRIPTEN_KEEPALIVE
# else
# define EM_PORT_API(rettype) rettype EMSCRIPTEN_KEEPALIVE
# endif
# else
# if defined(__cplusplus)
# define EM_PORT_API(rettype) extern "C" rettype
# else
# define EM_PORT_API(rettype) rettype
# endif
# endif
#endif
其中:
__EMSCRIPTEN__
宏用于探测是否是Emscripten环境
__cplusplus
用于探测是否C++环境
EMSCRIPTEN_KEEPALIVE
是Emscripten特有的宏,用于告知编译器后续函数在优化时必须保留,并且该函数将被导出至JavaScript
二、创建export.cc文件
代码如下:
//export1.cc
#ifndef EM_PORT_API
# if defined(__EMSCRIPTEN__)
# include <emscripten.h>
# if defined(__cplusplus)
# define EM_PORT_API(rettype) extern "C" rettype EMSCRIPTEN_KEEPALIVE
# else
# define EM_PORT_API(rettype) rettype EMSCRIPTEN_KEEPALIVE
# endif
# else
# if defined(__cplusplus)
# define EM_PORT_API(rettype) extern "C" rettype
# else
# define EM_PORT_API(rettype) rettype
# endif
# endif
#endif
#include <stdio.h>
EM_PORT_API(int) show_me_the_answer() {
return 42;
}
EM_PORT_API(float) add(float a, float b) {
return a + b;
}
三、编译文件
使用emcc编译export.cc文件:
emcc code/export.cc -o code/export.js
编译完成后的文件为:
四、创建export.html
在同路径下创建名为export.html的文件,用于显示及引用对应文件。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Emscripten:Export</title>
</head>
<body>
<script>
Module = {};
Module.onRuntimeInitialized = function() {
console.log(Module._show_me_the_answer());
console.log(Module._add(12, 1.0));
}
</script>
<script src="export.js"></script>
</body>
</html>
Module 作为全局对象,不用自行定义,且由Emscripten生成的JavaScript胶水代码基本都围绕全局对象Module展开。
onRuntimeInitialized 是一个注入方法,Emscripten的Runtime就绪后,将会回调该方法,以实现类似Module._main()的操作。
浏览器运行export.html文件后在F12中得到输出结果:
JavaScript调用C函数一般使用全局对象Module,格式为Module._[export fnc name]。例如:Module._show_me_answer();