如何使用Objective-C++从Objective-CCocoa接口调用C++方法
How to call C++ method from Objective-C Cocoa Interface using Objective-C++
现在我的OSX10.9项目已经在Objective-C中设置了一个GUI,所有处理都在C++类中。这似乎不是最好的方式,但这是给我的,我必须克服这些限制。我目前在Cocoa GUI中有一个NSSlider
。我希望能够让这个NSSlider
控制C++类中的变量x
。
目前,当我运行程序时,公差条正在工作(工作意味着它会根据我的滑动不断更新其值)。
NSSlider
(Slider.h
)的标题:
@interface Slider : NSObject {
@private
__weak IBOutlet NSTextField *sliderValue;
__weak IBOutlet NSSlider *slider;
}
- (IBAction)updateSliderValue:(id)sender;
@end
NSSlider
(Slider.mm
)的实现:
#import "Slider.h" // The NSSlider object
#import "CMain.h" // The C++ class that does all the processing (not sure if this is the way to include a C++ interface in an Objective-C++ class or if this will allow me to call its methods)
@implementation Slider
-(void) awakeFromNib {
[slider setIntValue:40];
[sliderValue setIntValue:[slider intValue]];
}
- (IBAction)updateSliderValue:(id)sender {
[sliderValue setIntValue:[slider intValue]];
// Here is where I'd think that if I have a setValueofX(int number) method in the C++ class
// I could call this somehow using objective-C++. I don't know if I can or how to call this method here
}
以下是Main.h
:中的相关片段
class CMain(){
public:
CMain();
void setValueofX(int number);
int getValueofX();
private:
int x;
};
如何将CMain.h
包含在Objective-C++
中(.h
文件或.mm
文件是哪个?如何?),以便调用CMain.h
中的方法?我该如何表述Objective-C中的方法调用以使用setValueofX(sliderValue)
设置x
的值?
如果需要更多信息,请告诉我!感谢您的帮助或想法!
谢谢!
调用setter的代码与C++中的代码相同。但是,您需要一个指向CMain对象的指针才能调用它上的方法。我不知道该对象当前所在的位置。如果另一个对象中还没有对象,那么您可能想要创建一个对象,只需声明一个实例变量CMain myCMain;
,然后在updateSliderValue:
中调用myCMain.setValueOfX( [slider intValue] );
即可。
至于在哪里包含C++类,这确实是您的选择。然而,如果您在头中使用任何C++,那么从普通.m文件中包含它将需要大量额外的工作。因此,一般情况下,我会在头中使用纯C和ObjC,而在.mm文件中只使用C++。您可以使用类扩展名(有时也称为"类延续")在.mm文件中声明额外的ivar,以将它们排除在标头之外。
如果你想了解更多关于ObjC++的信息,我在另一篇文章中详细回答了:我可以在编译和链接时将C++主函数和类从Objective-C和/或C例程中分离出来吗?这也链接到我作为嘉宾的一个播客,在那里我谈论了许多集成ObjC和C++的细节和技巧。
旁白:我希望这些不是你实际使用的名字和评论。从来没有一个ObjC类没有前缀(3个字母,苹果表示他们保留所有2个字母的前缀供自己使用,而且他们过去使用过无前缀的内部类名,这破坏了一些人的程序)。此外,"Slider"是一个坏名字,因为NSSlider是实际的滑块,听起来它应该是一个子类。您真的想称之为ISTSliderController或其他什么。
我发现了一个解决方案,注意到有一个现有的包装类CWrapper.h
,它是一个objective-C++实现类CWrapper.mm
。有一个CMain
变量实例化为cmain
。我为x
制作了一个getter方法,并简单地在封装器类+ (void) passX:(int) number;
中创建了一个静态方法,我在滑块类中调用了该方法。我选择了一个静态方法,因为对于这个应用程序,这个值在对象之间永远不必不同。我希望我在这里做出了正确的选择!
请参阅下面的代码更改:
我将其添加到Slider.h
文件中。
- (int)X;
我将getter和[CWrapper passX:[self getX]];
添加到Slider.mm文件中的updateSliderValue
方法中。
- (int)X {
return [slider intValue];
}
- (IBAction)updateSliderValue:(id)sender {
[sliderValue setIntValue:[slider intValue]];
[CWrapper passX:[self getX]];
}
这是我添加到CWrapper.h.的代码
+ (void) passX:(int) number;
这是我添加到CWrapper.mm.的代码
+ (void) passX:(int)num
{
cmain.setValueofX(num);
}
这里有一个所有objective-c和objective-c++的答案:
C主要h:
#ifndef Testing_CMain_h
#define Testing_CMain_h
@interface CCMain : NSObject
-(CCMain*) init;
-(void) dealloc;
-(void)setValueofX:(int)number;
-(int)getValueofX;
@end
#endif
CMain.mm:
#import <Foundation/Foundation.h>
#import "CMain.h"
class CMain {
private:
int x;
public:
CMain() : x(0) {}
void setValueofX(int number) {x = number;}
int getValueofX() const {return x;}
};
@interface CCMain ()
@property (nonatomic, assign) CMain* inst;
@end
@implementation CCMain
-(CCMain*) init
{
if (!_inst)
{
_inst = new CMain();
}
return self;
}
-(void) dealloc
{
delete _inst;
_inst = nil;
}
-(void)setValueofX:(int)number
{
_inst->setValueofX(number);
}
-(int)getValueofX
{
return _inst->getValueofX();
}
@end
如果你想使用C风格的函数,那么:
setValueofX(cmain_instance, value);
int val = getValueofX(cmain_instance);
这是因为C中的C++类函数与相同
void CMain::MyFunc(int X);
//vs..
void MyFunc(CMain* inst, int X);
两者完全相同。
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 调用专用模板时出错"no matching function for call to [...]"
- 选择要调用的构造函数
- C++为什么尽管我调用了void函数,它却不起作用
- 构造函数正在调用一个使用当前类类型的函数
- 变量没有改变?通过向量的函数调用
- 没有为自己的结构调用列表推回方法
- 调用'begin(int [n])'没有匹配函数
- 什么时候调用析构函数
- 如何用参数值调用函数(仅在运行时已知)
- std::cout.imbue()多重调用
- 函数何时会在c++中包含stack_Unwind_Resume调用