[英]How do I create a C++ callback invoked from JavaScript using JavaScriptCore on iOS?
I'm using JavaScript core to facilitate communication between C++ and JavaScript for an iOS project I'm working on. 我正在使用JavaScript核心来促进C ++和JavaScript之间正在进行我的iOS项目的通信。 The following works to invoke a javascript function from C++:
以下工作可从C ++调用javascript函数:
#include <JavaScriptCore/JavaScriptCore.h>
void myCPPFunction()
{
JSGlobalContextRef globalContext =
JSGlobalContextCreateInGroup(JSContextGroupCreate(), nullptr);
auto funcOutput = JSEvaluateScript(globalContext,
JSStringCreateWithUTF8CString(("function test() {
return 'hi'; } test();", nullptr, nullptr, 1, nullptr);
// funcOutput now contains a JSValue containing the
// return value of the function ('hi').
}
Now, I want to invoke a C++ function from the JavaScript. 现在,我想从JavaScript调用C ++函数。 For example, if I have a C++ function defined as follows:
例如,如果我具有如下定义的C ++函数:
double myCPPCallback(unsigned long x)
{
// do stuff
}
How do I invoke this C++ code from the JavaScript I'm currently running with JSEvaluateScript
? 如何从当前正在使用
JSEvaluateScript
运行的JavaScript中调用此C ++代码?
It is easiest to do with JSObjectMakeFunctionWithCallback to what you can provide JSObjectCallAsFunctionCallback declared by you that then calls your C++ functions. 最简单的方法是将JSObjectMakeFunctionWithCallback设置为可以提供的,由您声明的JSObjectCallAsFunctionCallback ,然后调用C ++函数。 Then you can call the callback in JavaScript code by name that you gave to it in JSObjectMakeFunctionWithCallback.
然后,您可以使用在JSObjectMakeFunctionWithCallback中为其指定的名称,在JavaScript代码中调用回调。
Also note that you should not perhaps use the very thing like ... 另请注意,您也许不应该使用...
JSGlobalContextRef globalContext =
JSGlobalContextCreateInGroup(JSContextGroupCreate(), nullptr);
... because that way you leak the group (result of JSContextGroupCreate()
). ...因为那样会泄漏组(
JSContextGroupCreate()
结果)。 I try to fabricate example OSX code (no time to test it): 我尝试制作示例OSX代码(没有时间对其进行测试):
#include <iostream>
#include <JavaScriptCore/JavaScriptCore.h>
JSValueRef HelloCallback( JSContextRef ctx
, JSObjectRef function
, JSObjectRef thisObject
, size_t argumentCount
, const JSValueRef arguments[]
, JSValueRef* exception)
{
// here do the C++ stuff
std::cout << "Hello World" << std::endl;
return JSValueMakeUndefined(ctx);
}
int main(int argc, const char * argv[])
{
// bad raw opaque pointers TODO: manage with smart pointers
JSContextGroupRef group = JSContextGroupCreate();
JSGlobalContextRef globalContext = JSGlobalContextCreateInGroup(group, nullptr);
JSObjectRef globalObject = JSContextGetGlobalObject(globalContext);
JSStringRef helloFunctionName = JSStringCreateWithUTF8CString("hello");
// make function object
JSObjectRef functionObject = JSObjectMakeFunctionWithCallback( globalContext
, helloFunctionName
, &HelloCallback);
// set it as proprty of global object
JSObjectSetProperty( globalContext
, globalObject
, helloFunctionName
, functionObject
, kJSPropertyAttributeNone
, nullptr );
// make javascript
JSStringRef statement = JSStringCreateWithUTF8CString("hello()");
// evaluate it
JSEvaluateScript( globalContext
, statement
, nullptr
, nullptr
, 1
, nullptr );
// manual raw pointer management ... hopefully did not forget any
JSGlobalContextRelease(globalContext);
JSContextGroupRelease(group);
JSStringRelease(helloFunctionName);
JSStringRelease(statement);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.