2009-07-27 92 views
2

我有一個C++類'Expression',它帶有一個我想在Objective-C類'GraphVC'中使用的方法。將C++方法傳遞給Objective-C方法

class Expression { 
    double evaluate(double); 
} 

我的Objective-C類:

@implementation GraphVC : UIViewController { 
- (void)plot:(double(*)(double))f; 
@end 

我認爲,這將是最容易的繞過該採取雙重並返回一個雙,而不是C++對象函數指針,但我使用functional.h沒有太大的成功。 Objective-C使用我的C++方法的最佳方式是什麼?

編輯:感謝您的快速回復。請允許我詳細闡述一下......我有一個用C++編寫的後端,我操縱Expression類型的對象。有理性,多項式,單項等的子類。我最初的想法是使用mem_fun,但我無法通過這種方式獲得代碼編譯。我也無法使用bind1st綁定this指針。

  • 編寫一個Objective-C的包裝是一種可能性,但我寧願使用現有evaluate()功能,我不想打破後端和iPhone GUI類之間的完全分離。
  • 我不能有一個全球性的表達或者使用一個靜態方法(我需要繪製任意Expression實例。

我應該有更明確地說,我需要通過一個C++成員函數(不是一個靜態函數或現有的C函數)到一個Objective-C對象有沒有人有幸使用C++的<functional>將成員函數轉換爲我可以在Objective-C對象中使用的指針,還是應該使用Objective-C包裝器?

回答

2

如果你想使一個指向C++的方法,你需要包括類名,像這樣:

class Foo 
{ 
    public: 
    double bar(double d) 
    { 
     return d; 
    } 
}; 

void call_using_obj_and_method(Foo *f, double (Foo::*m)(double d)) 
{ 
    (f->*m)(3.0); 
} 

int main() 
{ 
    Foo f; 
    call_using_obj_and_method(&f, &Foo::bar); 
    return 0; 
} 

請注意,您所需要的類的實例,以及。在我的例子中,這是另一個參數,儘管你可以讓它成爲一個全局變量,或者Foo類的單例實例。

雖然,像jkp說的那樣,您也可以通過使方法變爲靜態或將其轉換爲常規函數來解決問題。

編輯:我不知道我是否正確理解你的問題。我不認爲你需要使用功能。這是我的例子會怎樣看在Objective-C++:

#include <Cocoa/Cocoa.h> 

class Foo 
{ 
    public: 
    double bar(double d) 
    { 
     return d; 
    } 
}; 

typedef double (Foo::*fooMethodPtr)(double d); 

@interface Baz : NSObject 
{ 
} 
- (void)callFooObj:(Foo *)f method:(fooMethodPtr)m; 
@end 

@implementation Baz 
- (void)callFooObj:(Foo *)f method:(fooMethodPtr)m 
{ 
    (f->*m)(3.0); 
} 
@end 

int main() 
{ 
    Foo f; 
    Baz *b = [[Baz alloc] init]; 
    [b callFooObj:&f method:&Foo::bar]; 
    return 0; 
} 
0

如果你的C++成員函數返回一個double,你的代碼是不是看起來像這樣?

- (void)plot:(double)f; 

...

[self plot:myExpression.evaluate(aDouble)]; 

或類似的東西。我沒有使用Obj-C和C++的很多混合,但這是我如何接近它。如果你像這樣混合它們,你的Objective-C++文件也可能需要擴展名.mm。

+0

我想他想把一個函數傳給`plot:`方法,而不是一個單一的值。 – dreamlax 2009-07-27 13:09:10

1

我認爲這裏的問題是,您正嘗試將Expression類的成員函數傳遞給Objective-C類。這是行不通的,因爲它期待this指針作爲第一個參數傳遞給函數(因此該簽名是不一樣的一個由方法的預期。

如果使C++方法靜態的,你可以做這個,但是你不會爲了使用標準的C函數而自行購買很多東西。

IE,如果Expression類是這樣的:

class Expression { 
    static double evaluate(double); 
} 

你應該能夠這樣稱呼它:

[self plot:myExpression.evaluate(&Express::evalulate)]; 

正如我說的,雖然,沒有數額巨大因爲你可能會使用標準的C函數(除非你可以在C++類中做一些對你更有用的東西)。

我曾經看過試圖用objective-c方法橋接boost :: bind()結果,但沒有得到很好的結果。我相信如果你在C++運行時深入挖掘,你可以做到。

2

我建議包裝在一個Objective-C類C++類,然後還提供了

- (void) plotWithObject:(id)obj 
{ 
    double result = [obj evaluate: 1.5]; 
    // ... etc ... 
} 

除了劇情: 方法。