実際の問題の裏話は次のとおりです。
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 で clang を実行していますが、この問題は Windows の VS2012 にも悩まされています。