我在Cocoa应用程序中使用一个小型C ++库(atm只是一个非常简单的例子来了解我应该怎么做)。
所以我在命名空间中有一个小的C ++类,如下所示:
namespace testlib {
class Test {
public:
Test(unsigned a);
Test operator+(const Test& other) const;
Test operator+(unsigned other) const;
Test& operator+=(unsigned other);
Test& operator+=(const Test& other);
unsigned getValue() const;
private:
unsigned theValue;
};
}
然后我有一个带有以下代码的.h文件:
#import <Foundation/Foundation.h>
#import "testlib.h"
@interface test : NSObject {
testlib::Test* testClass;
}
- (id)init;
- (id)add: (unsigned)value;
- (unsigned)value;
- (void)dealloc;
@property void* testClass;
@end
最后是一个实现(在一个名为test.mm的文件中):
#import "test.h"
@implementation test
@synthesize testClass;
- (id)init {
testClass = new testlib::Test(0);
return self;
}
- (void)dealloc {
delete testClass;
[super dealloc];
}
- (id)add: (unsigned)value {
*testClass += value;
return self;
}
- (unsigned)value {
return testClass->getValue();
}
当我尝试编译时,我得到了以下错误:
CompileC build/testipod.build/Debug-iphonesimulator/testipod.build/Objects-normal/i386/WindowController.o WindowController.m normal i386 objective-c com.apple.compilers.gcc.4_2
cd /Users/sausalito/eth/testipod
setenv LANG en_US.US-ASCII
setenv PATH "/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2 -x objective-c -arch i386 -fmessage-length=0 -pipe -std=c99 -Wno-trigraphs -fpascal-strings -fasm-blocks -O0 -Wreturn-type -Wunused-variable -D__IPHONE_OS_VERSION_MIN_REQUIRED=30000 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.3.sdk -fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -iquote /Users/sausalito/eth/testipod/build/testipod.build/Debug-iphonesimulator/testipod.build/testipod-generated-files.hmap -I/Users/sausalito/eth/testipod/build/testipod.build/Debug-iphonesimulator/testipod.build/testipod-own-target-headers.hmap -I/Users/sausalito/eth/testipod/build/testipod.build/Debug-iphonesimulator/testipod.build/testipod-all-target-headers.hmap -iquote /Users/sausalito/eth/testipod/build/testipod.build/Debug-iphonesimulator/testipod.build/testipod-project-headers.hmap -F/Users/sausalito/eth/testipod/build/Debug-iphonesimulator -F/Users/sausalito/eth/testipod/../testlib/build -I/Users/sausalito/eth/testipod/build/Debug-iphonesimulator/include -I/Users/sausalito/eth/testipod/build/testipod.build/Debug-iphonesimulator/testipod.build/DerivedSources/i386 -I/Users/sausalito/eth/testipod/build/testipod.build/Debug-iphonesimulator/testipod.build/DerivedSources -include /var/folders/4f/4fSYMOmtHHSRoBf+XVFQ+k+++TM/-Caches-/com.apple.Xcode.502/SharedPrecompiledHeaders/testipod_Prefix-cwdputxcxpofoydkulngkdplqxbt/testipod_Prefix.pch -c /Users/sausalito/eth/testipod/WindowController.m -o /Users/sausalito/eth/testipod/build/testipod.build/Debug-iphonesimulator/testipod.build/Objects-normal/i386/WindowController.o
In file included from /Users/sausalito/eth/testipod/Classes/test.h:10,
from /Users/sausalito/eth/testipod/WindowController.m:10:
/Users/sausalito/eth/testipod/Classes/testlib.h:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'testlib'
In file included from /Users/sausalito/eth/testipod/WindowController.m:10:
/Users/sausalito/eth/testipod/Classes/test.h:13: error: expected specifier-qualifier-list before 'testlib'
/Users/sausalito/eth/testipod/Classes/test.mm:13:0 /Users/sausalito/eth/testipod/Classes/test.mm:13: error: type of property 'testClass' does not match type of ivar 'testClass'
我做错了什么?看起来它使用C编译器来编译头文件。
当我将成员声明为void *类型然后在实现中使用强制转换时,我可以将它包装在Objective-C类中。但这绝对不是最舒服的做法。
答案 0 :(得分:6)
将您的WindowController.m
重命名为WindowController.mm
。
如果文件名是.m
,整个“翻译单元”将在没有++的ObjC中编译。但是,在test.h
中,您要导入包含C ++代码的testlib.h
。这些C ++代码在C中无效,从而导致编译器错误。
顺便说一句,
- (id)init {
testClass = new testlib::Test(0);
return self;
}
你应该打电话给super的init:
- (id)init {
if ((self = [super init]))
testClass = new testlib::Test(0);
return self;
}
属性
@property void* testClass;
应返回测试*。
@property(readonly,assign) testlib::Test* testClass;
答案 1 :(得分:3)
如果您不想重命名该文件,您还可以通过打开文件的“信息”窗口,明确告诉XCode将“.m”文件编译为ObjC ++(单击主文件左侧窗格中的文件名) XCode窗口,然后点击蓝色I“信息”按钮)。将“文件类型”更改为“sourcecode.cpp.objcpp”。
对于示例应用程序,我只是重命名该文件,但如果您有一个不想进行批量重命名的现有代码库,则“文件类型”设置可以很方便。
答案 2 :(得分:1)
在“Compile Source As”下将构建设置更改为Objective-c ++,然后点击build