Calling a JS Function from C++
Let's say that we have a page with the following HTML/JS on it:
<html>
<head>
<script>
function ShowMessage(message)
{
document.getElementById('msg').innerHTML = message;
}
</script>
</head>
<body>
<div id="msg"></div>
</body>
</html>
Our goal is to call the JavaScript function ShowMessage()
from C++.
Calling the JS Function with EvaluateScript()
The easiest way to call ShowMessage()
from C++ is by evaluating a string of JavaScript.
// Use LoadListener::OnDOMReady to wait for page scripts to load
void MyApp::OnDOMReady(View* view) {
// Call ShowMessage() by evaluating a string of JavaScript
view->EvaluateScript("ShowMessage('Howdy!')");
}
Calling the JS Function with JSObjectCallAsFunction()
For greater performance and control, you can pass arguments directly to the Function object using JavaScriptCore's JSObjectCallAsFunction()
.
This API function also offers exception handling, overriding the this
object, and more.
See the API declaration for
JSObjectCallAsFunction()
here.
// Use LoadListener::OnDOMReady to wait for page scripts to load
void MyApp::OnDOMReady(View* view) {
// Get the JS execution context for the current page loaded in View
JSContextRef ctx = view->js_context();
// Get the ShowMessage function by evaluating a script. We could have
// also used JSContextGetGlobalObject() and JSObjectGetProperty() to
// retrieve this from the global window object as well.
JSValueRef func = view->EvaluateScript("ShowMessage");
// Check if 'func' is actually an Object and not null
if (JSValueIsObject(ctx, func)) {
// Cast 'func' to an Object, will return null if typecast failed.
JSObjectRef funcObj = JSValueToObject(ctx, func, 0);
// Check if 'funcObj' is a Function and not null
if (funcObj && JSObjectIsFunction(ctx, funcObj)) {
// Create a JS string from null-terminated UTF8 C-string, store it
// in a smart pointer to release it when it goes out of scope.
JSRetainPtr<JSStringRef> msg =
adopt(JSStringCreateWithUTF8CString("Howdy!"));
// Create our list of arguments (we only have one)
const JSValueRef args[] = { JSValueMakeString(ctx, msg.get()) };
// Count the number of arguments in the array.
size_t num_args = sizeof(args) / sizeof(JSValueRef*);
// Create a place to store an exception, if any
JSValueRef exception = 0;
// Call the ShowMessage() function with our list of arguments.
JSValueRef result = JSObjectCallAsFunction(ctx, funcObj, 0,
num_args, args,
&exception);
if (exception) {
// Handle any exceptions thrown from function here.
}
if (result) {
// Handle result (if any) here.
}
}
}
}
Updated over 5 years ago