翻译:云荒杯倾
Embind用于绑定C++函数和类到JavaScript,这样编译代码就能在js中以一种很自然的方式来使用。Embind也支持从C++调JavaScript的class。
Embind支持绑定大多数C++的结构,包括C++11和C++14中引入的。它只有一个明显的限制就是目前还不支持raw pointers with complicated lifetime semantics。
本文展示了如何使用EMSCRIPTEN_BINDINGS()块来创建函数、类、值类型、指针(包括原始和智能指针)、枚举和常量的绑定,以及如何为抽象类创建绑定,这些抽象类可以在JavaScript中被重写。它还简要介绍了如何管理传递给JavaScript的c++对象句柄的内存。
note:
Embind的灵感来自 Boost.Python,他们使用非常相似的方法定义绑定。
一个简单例子
下面的代码使用EMSCRIPTEN_BINDINGS()暴露了C++ lerp()函数给JavaScript。
// quick_example.cpp
#include <emscripten/bind.h>
using namespace emscripten;
float lerp(float a, float b, float t) {
return (1 - t) * a + t * b;
}
EMSCRIPTEN_BINDINGS(my_module) {
function("lerp", &lerp);
}
为了使用embind编译上例,请调用emcc的bing选项:
emcc --bind -o quick_example.js quick_example.cpp
生成的quick_example.js文件可以作为node模块加载,也可以使用<script>加载:
<!doctype html>
<html>
<script src="quick_example.js"></script>
<script>
console.log('lerp result: ' + Module.lerp(1, 2, 0.5));
</script>
</html>
当quick_example.js文件初始化加载后, EMSCRIPTEN_BINDINGS()中代码会运行。
所有通过Embind暴露的symblols都可以在Module对象获取。
类
暴露一个类给JavaScript需要比较复杂的绑定语句,比如:
class MyClass {
public:
MyClass(int x, std::string y)
: x(x)
, y(y)
{}
void incrementX() {
++x;
}
int getX() const { return x; }
void setX(int x_) { x = x_; }
static std::string getStringFromInstance(const MyClass& instance) {
return instance.y;
}
private:
int x;
std::string y;
};
// Binding code
EMSCRIPTEN_BINDINGS(my_class_example) {
class_<MyClass>("MyClass")
.constructor<int, std::string>()
.function(