C++自定义线程中创建 cef 对象
C++ create cef object in custom thread
我想要创建一个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( 总是返回 null 结果。我想发生这种情况是因为代码在自定义线程中运行,因为某些任务必须在特殊线程中执行。
我说的对吗?以及如何切换到 cef 线程以与 V8 引擎配合使用并与之同步?
我错了吗?为什么 V8 会创建一个空对象?
更新
我添加了 UI 线程切换。在那之后,我总是在 Hzmy 的静止中cef_v8value_create_object中出现"访问冲突读取位置"异常。
简而言之:您必须只能从有效线程访问 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。
chromiumembedded 文档包含以下内容:
因此,在使用javascript模型进行操作之前,您应该打开正确的连接。 如果 V8 当前不在上下文中,或者需要检索和存储对上下文的引用,则可以使用两种可用的 CefV8Context 静态方法之一。GetCurrentContext(( 返回当前正在执行 JS 的帧的上下文。GetEnteredContext(( 返回 JS 执行开始的帧的上下文。例如,如果帧 1 中的函数调用帧 2 中的函数,则当前上下文将是帧 2,输入的上下文将是帧 1。
数组、对象和函数只能创建、修改,如果是函数,则只有在 V8 在上下文中才能执行。如果 V8 不在上下文中,则应用程序需要通过调用 Enter(( 进入上下文,并通过调用 Exit(( 退出上下文。只应使用 Enter(( 和 Exit(( 方法:
在现有上下文之外创建 V8 对象、函数或数组时。例如,创建 JS 对象以响应本机菜单回调时。
在当前上下文以外的上下文中创建 V8 对象、函数或数组时。例如,如果源自 frame1 的调用需要修改 frame2 的上下文。
所以这就是为什么我无法创建对象但能够创建 js 字符串的原因。您还可以看到一般使用示例。
下面的代码解决了这个问题:
if (callbackCtxt.get() && callbackCtxt->Enter())
{
CefRefPtr<CefV8Value> object = CefV8Value::CreateObject(NULL);
// call ExecuteFunctionWithContext and perform other actions
callbackCtxt->Exit();
}
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 使用std::函数映射对象方法
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- C++自定义线程中创建 cef 对象
- 如何在Chromium嵌入式框架(CEF)中获得JS对象