Google 的 v8 文档描述了如何将全局函数添加到 JavaScript 上下文。我们可以使用 C++11 中的新 lambda 特性轻松实现类似 printf 的函数:
Handle<ObjectTemplate> global = ObjectTemplate::New();
global->Set(String::New("print"), FunctionTemplate::New(
[](const v8::Arguments &args) -> v8::Handle<v8::Value>
{
v8::String::AsciiValue ascii(args[0]);
std::cout << *ascii << "\n";
} ));
Persistent<Context> context = Context::New(NULL, global);
这适用于任何无状态或引用全局 C++ 变量(即std::cout
)的全局 JavaScript 函数。但是如果我们希望我们的全局 JavaScript 函数引用一个非全局 C++ 变量呢?例如,假设我们正在创建几个不同的 JavaScript 上下文,每个上下文都有自己的print
使用不同 C++ 的全局函数std::ostream
?如果 v8 函数模板使用std::function
对象而不是函数指针,我们会这样做:
Persistent<Context> create_context(std::ostream &out)
{
Handle<ObjectTemplate> global = ObjectTemplate::New();
global->Set(String::New("print"), FunctionTemplate::New(
[&out](const v8::Arguments &args) -> v8::Handle<v8::Value>
{
v8::String::AsciiValue ascii(args[0]);
out << *ascii << "\n";
} ));
return Context::New(NULL, global);
}
不幸的是,v8 似乎不支持这一点。我假设(希望?)v8 有一种做功能等效的方法,但我发现自己被 Doxygen 迷惑了v8::FunctionTemplate
。尝试过类似事情的人会愿意将这个过程提炼成更容易理解的东西吗?我还想了解如何创建绑定到现有的 C++ 对象的非全局实例的 JavaScript 对象的全局实例。