質問

私のバックグラウンドエクスペリエンスはC/C ++/C#です。

私はXcodeプロジェクトでC ++ライブラリを使用しています(具体的にはライブラリはPJSIPです)。ライブラリを使用するには、このようなコードにいくつかのコールバックを配線する必要があります。

siptest.m

#include < pjsua-lib/pjsua.h >

static void on_reg_state(pjsua_acc_id acc_id)
{
    // Do work
} 

static void Init()
{
   // pjsua_config and psjua_config_default are  defined in the header file from pjsip
    pjsua_config cfg;            
    psjua_config_default(&cfg);  

    cfg.cb.on_regstate = &on_reg_state;
 }

このC ++ sytnaxを客観的cに切り替えたい

だから私はしました:

 +(void) on_reg_state:(pjsua_acc_id) acc_id
 {
    // Do work
 } 

 +(void) Init
 {
    pjsua_config cfg;            
    psjua_config_default(&cfg);  

    cfg.cb.on_regstate = &on_reg_state; // ***** this is causing compile error
                                        // I tried [CLASS NAME on_reg_state] and i get   runtime error
 }

Objective Cでデリゲートを検索しようとしましたが、コールバックがC ++で既に実装されており、Objective-C Syntaxで使用する同様のケースを見つけることができませんでした。

ありがとう

役に立ちましたか?

解決

まず第一に、何も変換する必要はまったくありません。 Objective-CからC ++ライブラリを呼び出すことはまったく問題ありません。

第二に、コンパイラエラーの原因となるのは、関数ポインターが必要な場所にメソッドを固定しようとしていることです。次のこと & オペレーター。単にあなたを維持します on_reg_state() 以前と同じように機能して使用します。これが、AppleのCベースのフレームワークでコールバックを行う方法です(高レベルのObjective-C APIが提供するものを超えて移動するとすぐに必要です)。

そして第三に、あなた + (void)Init 方法は少し奇妙に見えます。私はあなたが電話と呼ばれる方法を書くことを強く落胆させます Init (大文字)。イニシャルを書くつもりなら、それは - (id)init, 、つまり小文字と帰還 id. 。また、スーパークラスの指定された初期イザーを呼び出し、その返品値を確認し、自己に割り当てて、最後に返すことを忘れないでください init 方法(参照 初期化の実装Appleのドキュメント あなたがそれに精通していないなら)。そして、あなたの方法が初期イザーでない場合は、別の名前を使用してください。 - (void)createConfig.

他のヒント

この場合、セレクターを使用する必要があります。

+(void) on_reg_state:(pjsua_acc_id) acc_id
 {
    // Do work
 } 

 +(void) Init
 {
    pjsua_config cfg;            
    psjua_config_default(&cfg);  

    cfg.cb.on_regstate_selector = @selector(on_reg_state:);
    cfg.cb.target = self; //Self here is the class object in your 'Init' method, which is poorly named.
    //Use this like [cfg.cb.target performSelector:cfg.cb.on_regstate_selector withObject:...etc]

 }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top