🕌
WASM Emscripten/Embind で int64_t が unknown type x になる
JavaScript の Number
型は 一般的にfloat64
型のため、int64
/uint64
型 をJavaScript側に公開すると 例外が送出される。
解決策
int64
/uint64
の暗黙の型変換を行わないので、公開側で明示的にdouble
に型変換を行う。
なお、double
の仮数部は 52bit なので、整数として扱える最大値は 4503599627370495
(0xfffff'ffffffff
)であることに注意する必要がある。
具体例
Array.push()
を呼び出した場合
WASM側で 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