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