2017-05-17 5 views
0

objective-C++関数ポインタを標準のC++に渡したいので、C++でobjective-cメソッドを呼び出すことができます。ここでobjective-C++から標準C++に関数を渡す方法はありますか?

は私が達成したいものです。

//C++ side 
class CppSide 
{ 
public: 
    void(*TestFunction)(); 
}; 

//objective-c++ side 
@interface InteropController : GLKViewController{ 
} 
-(void) PickFile; //I want to pass PickFile address to TestFunction 
@end 

後は私がやったことですが、

InteropController* controller = [[InteropController alloc] init]; 
CppSide* cppSide = new CppSide(); 
cppSide->TestFunction = [controller methodForSelector:@selector(PickFile:)]; 
cppSide->TestFunction(); //EXC_BADccess(code=1, address=0x2d) 

は、私はどのように行う必要があります動作しませんか?

答えて

3

怠け者で簡単な方法は、objCコードを呼び出すstd ::関数を渡すことです(例えば、ラムダを使って)。

しかし、そこには生のC関数ポインタがあります。あなたは、Cの関数を書く(または非キャプチャラムダを使用)する必要があります。

cppSide->TestFunction = [](){ ... ObjC Code here ...}; 

しかし、あなたがそこに親スコープを参照する手立てがない - 唯一のグローバルスコープにします。

あなたがのstd ::機能を使用する代わりに、それを変えることができれば、あなたがはるかに柔軟性があります:あなたは、いくつかの理由で、その関数ポインタ型を変更できない場合

cppSide->TestFunction = [=](){[controller PickFile: ... ];}; 

を、変更を検討それ、それは非常に少なくとも、データポインタを期待するように:

class CppSide 
{ 
public: 
    void(*TestFunction)(void *data); 
}; 

そして、あなたが行うことができます:

cppSide->TestFunction = [](void *data) { 
    InteropController* controller = static_cast<InteropController*>(data); 
    [controller PickFile: ... ]; 
} 

関数ポインタを呼び出す呼び出し元は、明示的にコントローラを渡す必要があります。

+1

ありがとうございました!これは素晴らしい。そして、私がやったことはセレクタの ':'を削除した直後であることが判明しました – Yonghui

+0

C++ 14標準を有効にすることをお勧めします。ラムダの方がはるかに良い(一般的なラムダを含む) – Arafangion

関連する問題