Chromium嵌入式如何从c ++执行javascript回调?

问题描述 投票:3回答:1

最近我一直试图将我的应用程序绑定到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);

$ simplixHandler是我自己的处理程序的一个实例。这是我的处理程序中的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);

我知道事件被调用(因为我首先因为类的错误链接而导致了nullpointer异常,现在已经修复了),但Javascript Callback没有被调用。

有谁知道我做错了什么?

提前致谢。

javascript c++ callback chromium-embedded
1个回答
0
投票

你可以使用html代码中的任何函数进行回调。

渲染:

bool SimpleApp::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
    CefProcessId source_process,
    CefRefPtr<CefProcessMessage> message) 
{
    std::string message_name = message->GetName();

    if( message_name == "FUNC")
    { 
        //AfxMessageBox("stop");

        //browser->GetMainFrame()->ExecuteJavaScript("super_test('works!');", browser->GetMainFrame()->->GetURL(), 0);

        CefRefPtr<CefV8Value> object = m_context->GetGlobal();


        CefRefPtr<CefV8Context> v8context = browser->GetMainFrame()->GetV8Context();
        v8context->Enter(); 

        CefRefPtr<CefV8Value> func_test = object->GetValue("super_test");

        if(func_test == NULL)
        {
            v8context->Exit();
            return false;
        }

        CefV8ValueList arguments;
        CefRefPtr<CefV8Value> test = CefV8Value::CreateString("hello from c++");
        arguments.push_back(test);

        CefRefPtr<CefV8Value> retval = func_test->ExecuteFunction(NULL, arguments);

        v8context->Exit();

        return true;
    }

    return false;
}

JScript的:

 <script>

      function super_test(resp)
      {
          alert(resp);
          return "7777";
      }

浏览器:

CefRefPtr<CefProcessMessage> message = CefProcessMessage::Create("FUNC");

        SimpleHandler::GetInstance()->GetBrowser()->SendProcessMessage(PID_RENDERER, message);
© www.soinside.com 2019 - 2024. All rights reserved.