【问题标题】:Chromium Embedded how to execute a javascript callback from c++?Chromium Embedded 如何从 c++ 执行 javascript 回调?
【发布时间】: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&lt;CefV8Value&gt; retval = func-&gt;ExecuteFunction(NULL, callArgs); 是真的被调用了,还是没有找到回调?

标签: javascript c++ callback chromium-embedded


【解决方案1】:

您可以使用 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    • 2014-02-03
    • 1970-01-01
    相关资源
    最近更新 更多