Совместно используемая библиотека, использующая v8, несовместима со статически связанной версией v8?

Вот некоторая предыстория реальной проблемы:

Я работаю над проектом, используя Chromium Embedded Framework (CEF) и v8 обеспечить привязку нативных функций C ++ к JavaScript, работающему во встроенном браузере.

В частности, я пытаюсь создать 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 через свою (динамическую) библиотеку.

Так вот в чем проблема:

После запуска проекта и вызова v8::Context::GetCurrent()сбой с EXC_BAD_ACCESS ошибка где-то в библиотеке v8. После дальнейших исследований я подтвердил, что в соответствии с API CEF мы являются в контексте после вызова context->Enter(), но в соответствии с API v8, мы не в контексте, который объясняет ошибку.

Из моего крайне ограниченного опыта работы с библиотеками C / C ++, мне кажется, что это означает, что код CEF v8 и мой код v8 выполняются в разных пространствах памяти. v8 — это статическая библиотека, а CEF — динамическая библиотека, так как это повлияет на нее?

Я хотел бы знать, почему это происходит, и что я могу сделать, чтобы это исправить или обойти это?

PS: я создаю это с использованием C ++ 11 и clang на Mac OS X через XCode, но эта проблема также мешает VS2012 на Windows.

1

Решение

Чтобы получить доступ к виртуальной машине V8, используемой CEF, вам придется создать CEF самостоятельно. Libcef.dll — это просто прокси C ++ to C ++ для «настоящего» libcef, который является статической библиотекой. Когда вы сами компилируете CEF, вы можете изменить свои программы так, чтобы они ссылались на эту статическую библиотеку, а не на библиотеку импорта для DLL.

Сделав это, вы теперь обязаны ссылаться на все те же статические библиотеки, на которые должна была ссылаться DLL. Это включает в себя V8. Теперь это позволит прямой доступ к тому же V8, который использует CEF. Он также удаляет код перевода C ++ в C ++, который CEF DLL использовал для взаимодействия с реальным кодом CEF. Это также даст вам прямой доступ к WebCore / WebKit, Chromium, V8 и любым другим библиотекам, которые используются теми, когда вы этого хотите или нуждаетесь.

Обратитесь к инструкции по сборке CEF: https://code.google.com/p/chromiumembedded/wiki/BranchesAndBuilding

После сборки библиотека, на которую вы хотите сослаться для CEF, — это libcef_static.lib.

0

Другие решения

Других решений пока нет …