【发布时间】:2015-04-15 08:21:52
【问题描述】:
最近我一直在尝试将我的应用程序绑定到 CEF,这个过程很慢,但在过去的几天里我取得了一些进展。但是有一件事我就是不能去工作。
我想要实现的是: 1. 在 Javascript 中注册回调函数(当我的应用程序中发生事件时将调用这些函数) 2. 保存回调。 3.当事件发生时,执行注册的回调。
现在我可以执行第 1 步和第 2 步,但第 3 步是问题所在。 我首先通过注册一个回调来测试它,然后在 Javascript 中使用 executeCallback() 函数调用它并且它工作正常。但是每当我尝试从 C++ 中执行回调时,它都不起作用。
我在 onContextCread() 中创建 setEventCallback
CefRefPtr<CefV8Value> object = context->GetGlobal();
CefRefPtr<CefV8Value> simplixObj = CefV8Value::CreateObject(NULL);
object->SetValue("simplix", simplixObj, V8_PROPERTY_ATTRIBUTE_NONE);
func = CefV8Value::CreateFunction("setEventCallback", $simplixHandler);
simplixObj->SetValue("setEventCallback", func, V8_PROPERTY_ATTRIBUTE_NONE);
$simplexHandler 是我自己的处理程序的一个实例。 这是我的处理程序中的 setEventCallback:
bool SimplixHandler::setEventCallback(CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval, CefString& exception)
if (arguments.size() == 2 && arguments[0]->IsString() && arguments[1]->IsFunction()) {
//Get name of callback
std::string callbackName = arguments[0]->GetStringValue();
//Get the current context
CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
//Insert into callbacks
$callbacks[callbackName] = std::make_pair(context, arguments[1]);
return true;
}
else if(arguments.size() != 2) {
exception = CefString("Invalid amount of parameters. Expected 2, received " + arguments.size());
return false;
}
else {
exception = CefString("Incompatible parameter types, expected (string, function).");
return false;
}
然后我尝试通过调用 executeCallback 来执行回调:
bool SimplixHandler::executeCallback(std::string name, CefRefPtr<CefListValue> list) {
bool handled = false;
if (!$callbacks.empty() && $callbacks.count(name) != 0) {
std::pair<CefRefPtr<CefV8Context>, CefRefPtr<CefV8Value>> pair = $callbacks[name];
CefRefPtr<CefV8Context> context = pair.first;
CefRefPtr<CefV8Value> func = pair.second;
context->Enter();
CefV8ValueList callArgs;
//First argument is function name
CefRefPtr<CefV8Value> args = CefV8Value::CreateArray(list->GetSize());
setList(list, args);
callArgs.push_back(args);
CefRefPtr<CefV8Value> retval = func->ExecuteFunction(NULL, callArgs);
if (retval.get()) {
if (retval->IsBool())
handled = retval->GetBoolValue();
}
context->Exit();
}
return handled;
}
我从我的 SimplixHandler 中调用此函数,但是我通过调用特定事件函数来调用回调,例如:
bool SimplixHandler::notifyDirectoryChanged(std::string directory) {
CefRefPtr<CefListValue> list = CefListValue::Create();
list->SetSize(1);
list->SetString(0, directory);
return executeCallback("onDirectoryChange", list);
}
最后是我的 Javascript:
function dirChange(dir) {
document.getElementById("filename").innerHTML = "It's something";
}
simplix.setEventCallback("onDirectoryChange", dirChange);
我知道该事件被调用(因为我首先由于类的错误链接而出现空指针异常,现在已修复),但没有调用 Javascript 回调。
有谁知道我做错了什么?
提前致谢。
【问题讨论】:
-
你在
SimplixHandler::executeCallback()中的CefRefPtr<CefV8Value> retval = func->ExecuteFunction(NULL, callArgs);是真的被调用了,还是没有找到回调?
标签: javascript c++ callback chromium-embedded