emscripten の bind で JavaScript オブジェクトを返す方法
2017-05-13 | [Programming]概要
emscripten を使うと,C++ のコードを JavaScript に変換することができる. さらに,Embind を使うと,C++ のコード中の関数などを JavaScript のコードから「自然に」呼び出すことができる. 例えば,C++ の関数の引数や戻り値として JavaScript のオブジェクトを使うことができる. ここでは,C++ から JavaScript オブジェクトを返す方法についてまとめておく.
int, std::string
int や std::string を返す C++ 関数は,そのまま bind できる.
JavaScript からは,int は数値型に,std::string は String に見える.
#include <emscripten.h>
#include <emscripten/bind.h>
#include <string>
using namespace emscripten;
int hoge() {
return 42;
}
std::string fuga() {
return "fuga";
}
EMSCRIPTEN_BINDINGS(mod) {
function("hoge", &hoge);
function("fuga", &fuga);
}JavaScript オブジェクトの操作
emscripten では,C++ から JavaScript オブジェクトを操作するために emscripten::val 型が用意されている.
使い方は ここ とか
ここ に書かれている.
例えば,
#include <emscripten.h>
#include <emscripten/bind.h>
using namespace emscripten;
val hoge(int i) {
val ret = val::object();
ret.set("height", val(i + 1));
ret.set("width", val(i + 100));
return ret;
}
EMSCRIPTEN_BINDINGS(mod) {
function("hoge", &hoge);
}このコードを用いて,JavaScript から Module.hoge(100) を呼び出すと, Object { height: 101, width: 200 } が得られる.
注意点として,プロパティの設定には set を用いないといけない.
例えば,ret.set("height", val(i + 1)); の代わりに ret["height"] = val(i + 1); と書いても,height は正しく設定されない.
配列
配列の要素の設定も,set を用いて行うことができる.
#include <emscripten.h>
#include <emscripten/bind.h>
using namespace emscripten;
val hoge(int i) {
val ret = val::object();
ret.set("height", val(i + 1));
ret.set("width", val(i + 100));
ret.set("data", val::array());
for (int x = 0; x < 10; ++x) {
ret["data"].set(x, x);
}
return ret;
}
EMSCRIPTEN_BINDINGS(mod) {
function("hoge", &hoge);
}val::call を使えば,push などを使って操作することもできる.
#include <emscripten.h>
#include <emscripten/bind.h>
using namespace emscripten;
val hoge(int i) {
val ret = val::object();
ret.set("height", val(i + 1));
ret.set("width", val(i + 100));
ret.set("data", val::array());
for (int x = 0; x < 10; ++x) {
ret["data"].call<val>("push", val(x));
}
return ret;
}
EMSCRIPTEN_BINDINGS(mod) {
function("hoge", &hoge);
}