这是真正问题的一些背景故事:
我正在使用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。答案 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。