以下是有关实际问题的一些背景知识:
我正在使用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/