1

以下是真正问题的一些背景故事:

我正在使用Chromium Embedded Framework (CEF) 和v8开发一个项目,以提供与在嵌入式浏览器中运行的 JavaScript 的原生 C++ 函数绑定。

具体来说,我正在尝试做的是v8::ObjectTemplate在加载任何页面或上下文之前构造 a ,然后在 CEF 的OnContextCreated回调中,创建该模板的新实例并将其作为属性添加到全局window对象上。

问题是 CEF 的 API 包装了 v8 上下文和值,为您提供了一个(智能)指向接口的指针,完全隐藏了它在幕后使用 v8 的事实。由于 CEF 施加的限制,如果我使用 CEF 的包装器,项目会变得更加混乱,所以我宁愿让 v8 工作。OnContextCreated这是我实现 CEF回调的精简版:

void ContextHandler::OnContextCreated(
  CefRefPtr<CefBrowser> browser,
  CefRefPtr<CefFrame> frame,
  CefRefPtr<CefV8Context> context)
{
  context->Enter();

  v8::HandleScope scope;
  v8::Handle<v8::Context> v8context = v8::Context::GetCurrent();
  v8::Handle<v8::Object> window = v8context->Global();
  // _appObj is a v8::Handle<v8::ObjectTemplate> member of ContextHandler
  window->Set(v8::String::New("app"), _appObj->NewInstance());

  context->Exit();
}

现在,请注意,虽然 CEF 在幕后使用 v8,但它并没有通过其 API 公开它。因此,检索上下文的 v8 版本的唯一方法是使用v8::Context::GetCurrent(),理论上它应该返回v8::Context被 包裹的内容CefV8Context

另请注意,为了编译它,我需​​要编译并链接一个单独的v8(静态)库,再次因为 CEF 不通过其(动态)库公开 v8。

所以这里的问题是

在运行项目并调用 时,它会在 v8 库中的某处发生错误v8::Context::GetCurrent()并崩溃。EXC_BAD_ACCESS经过进一步研究,我已经确认根据 CEF 的 API,我们调用 后处于上下文中context->Enter(),但根据 v8 的 API,我们不在上下文中,这解释了错误。

从我对 C/C++ 库的极其有限的经验来看,这似乎意味着 CEF 的 v8 代码和我的 v8 代码在不同的内存空间中运行。v8 是静态库,CEF 是动态库,对它有影响吗?

我想知道为什么会发生这种情况,我能做些什么来解决这个问题或解决这个问题?

PS:我正在使用 C++11 构建它,并通过 XCode 在 Mac OS X 上发出叮当声,但这个问题也困扰着 Windows 上的 VS2012。

4

1 回答 1

0

要访问 CEF 使用的 V8 VM,您必须自己构建 CEF。libcef.dll 只是“真实”libcef 的 C++ 到 C 到 C++ 代理,它是一个静态库。当您自己编译 CEF 时,您可以更改程序以链接到该静态库而不是 DLL 的导入库。

通过这样做,您现在需要链接到 DLL 必须链接到的所有相同的静态库。这包括 V8。现在,这将允许直接访问 CEF 正在使用的同一 V8。它还删除了 CEF DLL 用于与实际 CEF 代码交互的 C++ 到 C 到 C++ 的转换代码。这也将让您在需要或需要时直接访问 WebCore/WebKit、Chromium、V8 以及它们使用的任何其他库。

参考 CEF 的构建说明:https ://code.google.com/p/chromiumembedded/wiki/BranchesAndBuilding

构建后,您要为 CEF 链接的库是 libcef_static.lib。

于 2013-06-19T20:40:01.883 回答