使用v8的共享库与静态链接的v8不兼容?

时间:2013-02-17 02:31:44

标签: c++ shared-libraries v8 static-linking chromium-embedded

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

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

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

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

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。 / p>

所以这就是问题

在运行项目并点击对v8::Context::GetCurrent()的调用时,它会在v8库中的某处出现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。

1 个答案:

答案 0 :(得分:0)

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

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

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

一旦构建,您要链接到CEF的库是libcef_static.lib。