以下是有关实际问题的一些背景知识:

我正在使用Chromium Embedded Framework(CEF)和v8为在嵌入式浏览器中运行的JavaScript提供本机C ++函数绑定的项目。

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

问题在于,CEF的API包装了v8上下文和值,为您提供了一个(智能)指向接口的指针,从而完全隐藏了它在后台使用v8的事实。由于CEF施加的限制,如果我使用CEF的包装程序,该项目将变得更加混乱,因此我宁愿让v8正常运行。这是我对CEF的window回调的实现的精简版:

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版本的唯一方法是使用OnContextCreated,理论上,它应返回被v8::Context::GetCurrent()包裹的v8::Context

还要注意,为了进行编译,我需要编译并链接一个单独的v8(静态)库,因为CEF不会通过其(动态)库公开v8。

所以这是问题所在:

在运行项目并单击对CefV8Context的调用后,它在v8库中的某处因v8::Context::GetCurrent()错误而崩溃。经过进一步的研究,我确认根据CEF的API,我们在调用EXC_BAD_ACCESS之后处于上下文中,但是根据v8的API,我们不在上下文中,这说明了错误。

从我对C / C ++库的极为有限的经验来看,这似乎向我暗示CEF的v8代码和我的v8代码在单独的内存空间中运行。 v8是静态库,而CEF是动态库,那么这对它有影响吗?

我想知道为什么会这样,我该怎么做才能解决或解决此问题?

PS:我正在通过XCode在Mac OS X上使用C ++ 11和clang来构建它,但是这个问题也困扰着Windows上的VS2012。

最佳答案

要访问CEF使用的V8 VM,您必须自己构建CEF。 libcef.dll只是从C ++到C到C ++的“真实” libcef代理,后者是一个静态库。自己编译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。

关于c++ - 使用v8的共享库与静态链接的v8不兼容?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14917406/

10-12 23:28