[英]Passing a C++ method to an Objective-C method
I have a C++ class ' Expression
' with a method I'd like to use in my Objective-C class ' GraphVC
'.我有一个 C++ 类“
Expression
”,其中有一个我想在我的 Objective-C 类“ GraphVC
”中使用的方法。
class Expression {
double evaluate(double);
}
And my Objective-C class:还有我的 Objective-C 课程:
@implementation GraphVC : UIViewController {
- (void)plot:(double(*)(double))f;
@end
I thought that it would be easiest to pass around function pointers that take a double and return a double, as opposed to C++ objects, but I haven't had much success using functional.h
.我认为传递带有双精度值并返回双精度值的函数指针是最容易的,而不是 C++ 对象,但是我使用
functional.h
.h 并没有取得太大的成功。 What's the best way to use my C++ method from Objective-C?从 Objective-C 使用我的 C++ 方法的最佳方法是什么?
EDIT: Thanks for your quick responses.编辑:感谢您的快速回复。 Allow me to elaborate a bit... I have a backend written in C++ where I manipulate objects of type Expression.
请允许我详细说明一下...我有一个用 C++ 编写的后端,我可以在其中操作 Expression 类型的对象。 There's subclasses for rational, polynomial, monomial, etc. My initial idea was to use mem_fun from , but I wasn't able to get code compiling this way.
有理数、多项式、单项式等的子类。我最初的想法是使用mem_fun from ,但我无法以这种方式编译代码。 I also had trouble using bind1st to bind the
this
pointer.我也无法使用 bind1st 绑定
this
指针。
evaluate()
function, and I don't want to break the clean separation between the backend and the iPhone GUI classes.evaluate()
函数,而且我不想打破后端和iPhone GUI 类之间的清晰分离。Expression
instances.Expression
实例。 I should have more explicitly stated that I need to pass a C++ member function (not a static function or existing C function) to an Objective-C object.我应该更明确地声明我需要将 C++ 成员函数(不是静态函数或现有的 C 函数)传递给 Objective-C 对象。 Has anyone had luck using C++'s
<functional>
to turn member functions into pointers I can use in an Objective-C object, or should I use an Objective-C wrapper?有没有人使用 C++ 的
<functional>
将成员函数转换为我可以在 Objective-C 对象中使用的指针,还是应该使用 Objective-C 包装器?
If you want to make a pointer to a method in C++, you need to include the class name, like this:如果要在 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;
}
Note that you need an instance of the class as well.请注意,您还需要一个类的实例。 In my example this is another parameter, though you could let it be a global variable, or a singleton instance of class Foo.
在我的示例中,这是另一个参数,尽管您可以将其设为全局变量,或者类 Foo 的单例实例。
Though, like jkp said, you can also solve the problem by making the method static or turning it into a regular function.不过,就像 jkp 所说的,您也可以通过使方法静态或将其转换为常规函数来解决问题。
EDIT: I'm not sure if I understand your question correctly.编辑:我不确定我是否正确理解您的问题。 I don't think you need to use functional.
我认为您不需要使用功能性。 Here is how my example would look in Objective-C++:
下面是我的示例在 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;
}
I would suggest wrapping the C++ class in an Objective-C class, and then also providing a我建议将 C++ 类包装在一个 Objective-C 类中,然后还提供一个
- (void) plotWithObject:(id)obj
{
double result = [obj evaluate: 1.5];
// ... etc ...
}
in addition to the plot: method.除了情节:方法。
I think the problem here is that you are trying to pass a member function of your Expression
class to the Objective-C class.我认为这里的问题是您试图将
Expression
类的成员函数传递给 Objective-C 类。 This will not work because it's expecting a this
pointer as the first argument to that function (therefore the signature is not the same as the one expected by the plot:
method.这将不起作用,因为它期望
this
指针作为该函数的第一个参数(因此签名与plot:
方法期望的签名不同。
If you make the C++ method a static, you can do this, but then you don't buy yourself a lot over using a standard C function.如果您使 C++ 方法成为静态方法,则可以这样做,但是您不会因为使用标准 C 函数而付出太多代价。
IE, if the Expression
class looked like this: IE,如果
Expression
类如下所示:
class Expression {
static double evaluate(double);
}
You should be able to call it like this:你应该可以这样称呼它:
[self plot:myExpression.evaluate(&Express::evalulate)];
As I say though, there isn't a huge amount of value in this because you may as well be using a standard C function (unless you can do something in the C++ class that is more useful to you).不过,正如我所说,这并没有太大的价值,因为您也可能使用标准的 C 函数(除非您可以在 C++ 类中做一些对您更有用的事情)。
I did once look at trying to bridge boost::bind() results with objective-c methods but didn't get very far.我曾经尝试过使用 Objective-c 方法来桥接 boost::bind() 结果,但并没有走得太远。 I'm sure if you dig deep enough in the C++ runtime you could do it though.
我敢肯定,如果您在 C++ 运行时中挖掘得足够深,您可以做到。
If your C++ member function returns a double, can't your code just look like this?如果你的 C++ 成员函数返回一个 double,你的代码不能看起来像这样吗?
- (void)plot:(double)f;
... ...
[self plot:myExpression.evaluate(aDouble)];
Or something similar.或者类似的东西。 I've not used much mixing of Obj-C and C++, but this is how I would approach it.
我没有使用太多 Obj-C 和 C++ 的混合,但这就是我将如何处理它。 You also might have to have a .mm extension on your Objective-C++ file if you're mixing them like that.
如果你像这样混合它们,你可能还需要在你的 Objective-C++ 文件上有一个 .mm 扩展名。
Why wouldn't you pass the instantiated c++ class around inside an NSValue and then call the c++ method directly?为什么不在 NSValue 内部传递实例化的 c++ 类,然后直接调用 c++ 方法?
- (NSValue*)getExpression
{
Expression* e = new Expression();
return [[NSValue alloc] initWithPointer:e];
}
- (void)callExpression(NSValue*)expression
{
Expression* e = [expression pointerValue];
e->evaluate();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.