2013-03-08 10 views
5

まず、Firebreathで何をしているのかについての背景を説明します。firebreath JSAPIはfirefoxで認識されません

  1. firebreathを使用してブラウザでレンダリングビューアのプラグインを開発しています。
  2. 私はプラグインで2つのMIMEタイプを定義します.1つはメインビューア用で、もう1つは2D平面図用です。
  3. 各ページでは、1つのメインビューアのみが許可されますが、複数の2D平面図を表示できます。そしてそれらはすべてメインビューアで開かれた同じモデルのドキュメントを共有します。
  4. したがって、2D平面図をインスタンス化した後、ドキュメントオブジェクト(firebreath JSAPI)を平面図ビューに渡す必要があります。

その後、両方の「mainviewer」と「平面視」と名付けロードされ、メインビューアーとプランビューを想定して、私は問題がある

planview.attach(mainviewer.doc); 
(the signature is "bool attach(const FB::JSObjectPtr& myDoc)" and 
The mainviewer.doc is just a firebreath JSAPI) 

、以下のようにビューアを計画するドキュメントをattchますFirefoxでは、渡されたのJSObjectが

FB::JSAPIPtr jsAPI = myDoc->getJSAPI(); // THIS WILL RETURN **NULL**. 
m_main_doc = FB::ptr_cast<LcFbViewerDocumentAPI>(jsAPI); // Cast to my document API. 

を呼び出すことにより、JSAPIとして認識できないことをホストブラウザは、Firefoxは、IE /クロームがうまく機能しているとき、この問題にのみ発生します。

Firefoxを使用すると、渡されたJSAPIはどうなりましたか?

答えて

4

ほとんどのブラウザ(FireFoxを含む)は、別の関数呼び出しに渡す前にNPObjectsをラップします。このため、もともとブラウザに渡した基盤となるC++クラスにはアクセスできません。 FireBreathは実際のNPJavascriptObject(FireBreathがJSAPIオブジェクトをラップしてブラウザに渡すために使用するNPObject)に到達できないため、元のJSAPIオブジェクトにも到達できません。

JSAPIオブジェクトのインスタンスごとに静的IDを作成することを検討してください。その後、instance_idをJSAPIプロパティとして公開し、マップにオブジェクトを取得するために使用できるグローバルstd :: mapを作成できます。

// in the class def 
static int counter; 
int instance_id; 

// In the .cpp file 
int MyPluginAPI::counter(0); 

std::map<int, FB::JSAPIWeakPtr> apiMap; 
FB::JSAPIPtr getJSAPIObjectById(int id) { 
    std::map<int, FB::JSAPIWeakPtr> fnd = apiMap.find(id); 
    if (fnd != apiMap.end()) { 
     return fnd.second->lock(); // it's a weak pointer, lock to get the shared_ptr 
    } else { 
     return FB::JSAPIPtr(); // Alternately throw an exception 
    } 
} 

MyPluginAPI::MyPluginAPI() { 
    instance_id = counter++; 
    // Note that you can't get at the shared_ptr in the constructor, 
    // so you'll have to call an init function after creating the JSAPI object 

    registerProperty("instance_id", 
       make_property(this, 
        &FBTestPluginAPI::get_instId)); 
} 

int MyPluginAPI::get_instId() { return instance_id; } 

void MyPluginAPI::init() { 
    apiMap[instance_id] = shared_from_this(); 
} 

あなたがマップを通過し、期限切れの弱いPTRSをクリアしていない場合、これは当然のことながら、最終的に少量のメモリリークが発生しましたが、それはあなたが必要なものを与える必要があります。 JSAPIPtrオブジェクトでなければならないオブジェクトを取得すると、それをJSObjectPtrとして期待できます。

void doSomethingWithAnAPI(const FB::JSObjectPtr& obj) { 
    if (obj) { 
     int id = obj->GetProperty("instance_id"); 
     FB::JSAPIPtr ptr = getJSAPIObjectById(id); 
     if (ptr) { 
      // Hurray! We have the object 
     } 
    } 
} 

私は上記のコードをテストしていませんが、かなり近いはずです。

+1

タクシーはありがとう、これは私が必要なものです。 –

+1

ちなみに、Firebreathは、プラグイン専用のものではなく、機能開発に役立つ素晴らしいフレームワークです。 –

関連する問題