🕌
WASM Emscripten/Embind で int64_t が unknown type x になる
JavaScript の Number型は 一般的にfloat64 型のため、int64/uint64型 をJavaScript側に公開すると 例外が送出される。
解決策
int64/uint64の暗黙の型変換を行わないので、公開側で明示的にdoubleに型変換を行う。
なお、double の仮数部は 52bit なので、整数として扱える最大値は 4503599627370495(0xfffff'ffffffff)であることに注意する必要がある。
具体例
WASM側で Array.push() を呼び出した場合
WASM側
emscripten::val get_array() {
auto val = emscripten::val::array();
int64_t answer = 42;
val.call<emscripten::val>("push", answer);
return val;
}
EMSCRIPTEN_BINDINGS(my_module) {
function("get_array", &get_array);
}
$ my_module.get_array()
BindingError: parameter 1 has unknown type x
解決策
emscripten::val get_array() {
auto val = emscripten::val::array();
int64_t answer = 42;
val.call<emscripten::val>("push", static_cast<double>(answer));
return val;
}
$ my_module.get_array()
[42]
公開関数の引数に int64_t を定義し、JavaScript側から呼び出した場合
WASM側
std::int64_t func(std::int64_t x) {
return x + 42;
}
EMSCRIPTEN_BINDINGS(my_module) {
function("func", &func);
}
$ my_module.func(0)
UnboundTypeError: Cannot call func due to unbound types: x
解決策
std::int64_t func(std::int64_t x) {
return x + 42;
}
EMSCRIPTEN_BINDINGS(my_module) {
function("func", optional_override([](double x) -> double {
return func(x);
}));
}
$ my_module.func(0)
42
Discussion