2009-07-27 3 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. Каков наилучший способ использования моего метода C++ из Objective-C?

EDIT: Спасибо за ваши быстрые ответы. Позвольте мне немного уточнить ... У меня есть бэкэнд, написанный на C++, где я манипулирую объектами типа Expression. Есть подклассы для рационального, полиномиального, одночленного и т. Д. Моя первоначальная идея заключалась в использовании mem_fun, но я не смог получить компиляцию кода таким образом. У меня также возникли проблемы с использованием bind1st для привязки указателя this.

  • Пишем Objective-C обертку возможности, но я предпочел бы использовать уже существующую evaluate() функции, и я не хочу, чтобы разорвать четкое разделение между серверным и классами iPhone GUI.
  • Я не могу иметь глобальное выражение или использовать статический метод (мне нужно построить произвольные Expression экземпляров.

я должен более четко указано, что мне нужно передать ++ функцию-член C (не статический функции или существующей функции C) объекту Object-C. Кому-то повезло с использованием <functional> C++ для включения функций-членов в указатели, которые я могу использовать в объекте 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, вы также можете решить проблему, сделав метод статическим или превратив его в обычную функцию.

EDIT: Я не уверен, правильно ли понимаю ваш вопрос. Я не думаю, что вам нужно использовать функциональность. Вот как мой пример будет выглядеть в 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++, но так я подхожу к нему. Возможно, вам также понадобится расширение .mm в файле Objective-C++, если вы их смешаете.

+0

Я думаю, что он хочет передать функцию методу 'plot:', а не одному значению. – dreamlax

1

Я думаю, проблема в том, что вы пытаетесь передать членную функцию вашего класса Expression классу Objective-C. Это не будет работать, потому что он ожидает this указателя в качестве первого аргумента этой функции (поэтому подпись не совпадает с ожидаемым методом plot:.

Если вы сделаете метод C++ статическим, то вы можете сделать это, но тогда вы не купите себя много, используя стандартную функцию C.

IE, если Expression класс выглядел следующим образом:

class Expression { 
    static double evaluate(double); 
} 

Вы должны быть в состоянии назвать это так:

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

Как я уже говорил, хотя, не существует огромное количество от стоимости, потому что вы также можете использовать стандартную функцию C (если вы не можете сделать что-то в классе C++, который вам более полезен).

Я как-то попытался скомпоновать результаты boost :: bind() с помощью методов object-c, но не очень далеко. Я уверен, что если вы копаете достаточно глубоко в C++, вы можете это сделать.

2

Я хотел бы предложить оберточной класс C++ в классе Objective-C, а затем также обеспечивает

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

в дополнение к сюжету : метод.

Смежные вопросы