2013-05-14 55 views
3

我有一個C++類需要調用使用一個指向方法的目標C方法的函數指針的目標C的方法。此方法返回void,並接受一個類型爲'status'的參數,其中status是一個簡單的整數枚舉。調用使用從C++方法

enum status 
{ 
     status_valid = 0, 
     status_invalid, 
     status_unknown 
}; 

我有設置爲這樣的obj-c方法的指針。指針的方法也被傳遞到C++類和正在舉行上

typedef void (*FuncPtr) (status); 
FuncPtr myObjCSelectorPointer = (void (*)(status))[self methodForSelector:@selector(statusChanged:)]; 
cppClassInstance->setFuncPointer(myObjCSelectorPointer) 

myObjCSelectorPointer由cppClass這樣的:

void cppClass::setFuncPointer(FunctPtr *ptr) 
{ 
    this->funcPtr = ptr; 
} 

現在別的地方,當我試圖調用法指出,通過該指針,就像這樣:

status s; 
funcPtr(s); 

該方法被正確調用,但傳遞到方法的值丟失。 obj-c方法接收完全隨機的值。當我嘗試使用相同的方式調用cpp類中的方法時,它會傳遞並接收正確的值。

我在做什麼錯?你不能像這樣調用一個客觀的c方法嗎?

+0

後的狀態定義,我猜測,但嘗試通過引用傳遞狀態 – makc

+0

我向帖子添加了狀態定義。另外,我試圖通過引用來傳遞它,但那也沒有效果。我也有同樣的問題。 – halfwaythru

+0

@halfwaythru您的函數原型是錯誤的 - 請參閱我的答案。 – 2013-05-14 18:44:49

回答

6

的問題是,Objective-C的方法函數簽名並不像你想象的那麼簡單。爲了使面向對象的編程成爲可能,Objective-C方法採用兩個隱式參數:調用對象和選擇器發送 - id self, SEL _cmd - 這些需要傳遞。您需要獲得一個對象來調用該方法,並且您也應該存儲選擇器。然後,你的函數類型定義更改爲正確的一個:

typedef void (*FuncPtr) (id, SEL, status); 

要讀:[1][2](靠近部分typedef id (*IMP)(id, SEL, ...)

+0

這聽起來很有用,但有兩點:1.)如果函數原型不正確,那麼它不應該導致函數沒有被調用?我的obj-c方法在這個原型中被調用得很好。 2.)當我嘗試更改函數ptr原型時,我需要將其包含在C++頭中,其中'id'是未聲明的標識符。我如何繞過這個? – halfwaythru

+0

@halfwaythru 1.爲什麼它應該導致函數沒有被調用?編譯器發出'CALL'指令就好了...... 2.編譯爲Objective-C++。 – 2013-05-14 18:56:34

+0

@halfwaythru 1)no。它仍然會被調用,並且可能導致未定義的行爲。 2)objc運行時是C#''#include '或者H2CO3之前說的,你也可以將它編譯爲objC++。 – justin