1

実際の問題の裏話は次のとおりです。

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 にも悩まされています。

4

1 に答える 1

0

CEF が使用する V8 VM にアクセスするには、自分で CEF を構築する必要があります。libcef.dll は、静的ライブラリである「実際の」libcef への単純な C++ から C への C++ プロキシです。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 です。

于 2013-06-19T20:40:01.883 に答える