首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++在自定义线程中创建cef对象

C++在自定义线程中创建cef对象
EN

Stack Overflow用户
提问于 2013-09-30 07:24:34
回答 2查看 5.3K关注 0票数 3

我尝试创建一个javascript对象,将其传递给一个函数-回调,如下所示:

代码语言:javascript
复制
void MyClass::ThreadTaskOnSuccess(CefRefPtr<CefV8Value> callback, CefRefPtr<CefV8Context> callbackCtxt)
{
    if (!CefCurrentlyOn(TID_UI))
    {
        // switch to UI thread
        CefPostTask(TID_UI, NewCefRunnableMethod(this, &NewDownloadObject::CreateTempDownloadOnSuccess, callback, callbackCtxt));
        return;
    }
    // String creation works perfect!
    // CefRefPtr<CefV8Value> executionResult = CefV8Value::CreateString("test");

    // "Access violation" will be thrown
    CefRefPtr<CefV8Value> executionResult = CefV8Value::CreateObject(NULL);

    executionResult->SetValue("size", CefV8Value::CreateInt(123), V8_PROPERTY_ATTRIBUTE_NONE);
    executionResult->SetValue("fileName", CefV8Value::CreateString("some name of file"), V8_PROPERTY_ATTRIBUTE_NONE);

    CefV8ValueList args;
    args.push_back(executionResult);
    CefRefPtr<CefV8Value> retval;
    CefRefPtr<CefV8Exception> exception;
    if (callback->ExecuteFunctionWithContext(callbackCtxt, callbackCtxt->GetGlobal(), args, retval, exception, false))
    {
        if (exception.get())
        {
            throw CFdmException(exception->GetMessage().c_str());
        }
        else
        {
            // Execution succeeded.
        }
    }
}

但是CefV8Value::CreateObject( null )总是返回空结果。我猜这是因为代码是在自定义线程中运行的,因为有些任务必须在一个特殊的线程中执行。

我说的对吗?以及如何切换到cef线程来使用V8引擎并与其同步?

我说错了吗?以及为什么V8创建一个空对象?

更新的

我增加了UI线程切换。之后,我在cef_v8value_create_object中总是有“访问冲突读取位置”的异常,就像在Hzmy的提问中一样。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-01 07:07:10

嵌入铬的文档包含以下内容:

因此,在使用javascript模型操作之前,您应该打开正确的contect。如果V8当前不在上下文中,或者需要检索和存储对上下文的引用,则可以使用两个可用的CefV8Context静态方法之一。GetCurrentContext()返回当前正在执行JS的框架的上下文。GetEnteredContext()返回JS执行开始的框架的上下文。例如,如果frame1中的一个函数在frame2中调用一个函数,那么当前上下文将是frame2,而输入的上下文将是frame1。 数组、对象和函数只能在V8位于上下文中的情况下才能创建、修改和执行。如果V8不在上下文中,那么应用程序需要通过调用Enter()输入上下文,并通过调用Exit()退出上下文。只应使用Enter()和Exit()方法:

  1. 在现有上下文之外创建V8对象、函数或数组时。例如,在响应本机菜单回调创建JS对象时。
  2. 在当前上下文以外的上下文中创建V8对象、函数或数组时。例如,如果来自frame1的调用需要修改frame2的上下文。

这就是为什么我不能创建一个对象,但是能够创建js字符串的原因。你也可以看到一般用法示例

下面的代码解决了这个问题:

代码语言:javascript
复制
if (callbackCtxt.get() && callbackCtxt->Enter())
{
    CefRefPtr<CefV8Value> object = CefV8Value::CreateObject(NULL);
    // call ExecuteFunctionWithContext and perform other actions

    callbackCtxt->Exit();
}
票数 1
EN

Stack Overflow用户

发布于 2013-09-30 08:21:41

简而言之:您必须只从有效线程访问V8。

您可能想念如何在客户端应用程序中使用V8 JavaScript集成 wiki页面。

使用CEF3、WebKit和JS,在单独的呈现程序进程中运行。呈现程序进程中的主线程标识为TID_RENDERER,并且必须在该线程上执行所有V8。应该使用异步回调来设计浏览器和呈现程序进程之间通信的JS API。有关示例,请参见http://www.chromium.org/developers/design-documents/extensions/how-the-extension-system-works/api-pattern-design-doc

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19088594

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档