[英]How to call C++ method from Objective-C Cocoa Interface using Objective-C++
現在,我的OS X 10.9項目在Objective-C中設置有GUI,並且所有處理都在C ++類中。 這似乎不是最好的方法,但這是給我的,我必須處理這些約束。 我目前在可可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;
};
如何在Objective-C++
(包括.h
文件或.mm
文件?如何?)中包含CMain.h
,以便可以調用CMain.h
的方法? 我該如何用setValueofX(sliderValue)
在Objective-C中調用該方法來設置x
的值?
請讓我知道是否需要更多信息! 任何幫助或想法表示贊賞!
謝謝!
調用設置器的代碼與C ++中的代碼相同。 但是,您需要一個指向CMain對象的指針才能調用它上的方法。 我不知道該對象當前位於何處。 如果另一個對象中還沒有對象,則可能要創建一個對象,只需聲明一個實例變量CMain myCMain;
然后調用myCMain.setValueOfX( [slider intValue] );
在updateSliderValue:
。
至於在哪里包括C ++類,這實際上是您的選擇。 但是,如果您在標頭中使用任何C ++,則需要大量的額外工作才能將它們包含在純.m文件中。 因此,通常我會嘗試在標頭中使用普通C和ObjC,並且僅在.mm文件中使用C ++。 您可以使用類擴展名(有時也稱為“類延續”)在.mm文件中聲明其他ivars,以將其保留在標頭之外。
如果您想了解有關ObjC ++的更多信息,我在另一篇文章中詳細回答了: 我可以在編譯和鏈接時將C ++主要函數和類與Objective-C和/或C例程分開嗎? 這也鏈接到一個Podcast,我是一個嘉賓,在這里我談論了許多集成ObjC和C ++的細節和技巧。
除了:我希望這些不是您使用的實際名稱和注釋。 永遠不要有沒有前綴的ObjC類(3個字母,Apple表示他們保留所有2個字母的前綴供自己使用,並且過去使用的是不帶前綴的內部類名稱,這破壞了某些人的程序)。 另外,“ Slider”是一個壞名字,因為NSSlider是實際的滑塊,聽起來像它應該是子類。 您真的想將其稱為ISTSliderController或其他名稱。
我發現一個解決方案是注意到存在一個包裝類CWrapper.h
,它是一個目標C ++實現類CWrapper.mm
。 有一個CMain
變量實例化為cmain
。 我為x
創建了一個getter方法,然后在包裝類+ (void) passX:(int) number;
創建了一個靜態方法+ (void) passX:(int) number;
我在滑塊類中調用過的。 我選擇了靜態方法,因為對於該應用程序,此值在對象之間永遠不必相同。 希望我在這里做出了正確的選擇!
請參閱下面的代碼更改 :
我將此添加到Slider.h
文件中。
- (int)X;
我添加了吸氣劑和[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 ++的答案:
CMain.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);
兩者是完全一樣的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.