混合使用 Objective-C,(*.m,*.mm 和 .c/.cpp) 文件

15
在我的项目中,核心库是由C/C++文件组成的,而UI需要用Objective C开发。我能够从Objective C/.mm文件中访问/调用C++函数,但反过来就不行了,也就是说,我无法从C++文件中调用Objective C函数,当我尝试包含Objective C头文件时,甚至包括系统头文件时都不行。
#import <foundation/foundation.h> 

我遇到了1000多个编译错误,

就像这样的情况。

/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:180:0 /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:180: error: expected unqualified-id before '@' token


/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:182:0 /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:182: error: expected initializer before '*' token


/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:183:0 /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:183: error: 'NSString' was not declared in this scope


/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:183:0 /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:183: error: 'aSelectorName' was not declared in this scope

我是否需要添加一些预编译标志等?有没有人可以向我建议,在不太修改 C++ 代码的情况下,最好的方法来调用/访问继承自 NSObject 的 Objective-C 类,我只需要调用一个函数。

头文件的代码结构/包含顺序如下:

Some system header file
Some Core Class Header file 

#import <foundation/foundation.h>

2
<foundation/foundation.h> 应该改为 <Foundation/Foundation.h>。 - user557219
@Bavarious:尽管默认情况下HFS+不区分大小写,因此它可能会像现在这样工作。 - JeremyP
1
@JeremyP 是的,因此使用“应该”而不是“必须”。=)他的代码在大小写敏感的文件系统中编译时将会出错。 - user557219
5个回答

50
如果您有一个包含C++代码并需要使用Objective-C的.cpp文件,可以将该文件重命名为.mm或向编译器传递-x objective-c++参数。

1
我们如何将此参数传递给编译器?我们能在项目设置中找到吗? - AmineG
2
在这种情况下,右键单击项目树上的文件,选择“获取信息”,在“文件类型”中选择“sourcecode.cpp.objcpp”。这将告诉Xcode使用“-x objective-c++”编译该文件。 - user557219
3
我使用Xcode 4.6在项目级别上设置了“-x objective-c ++”作为我的项目的“Apple LLVM Compiler 4.2-Language”下“Build Settings”选项卡中“Other C++ Flags”和“Other C Flags”的值。 - NoobsArePeople2

4

我发现在C++头文件中使用任何Objective-C是不可能的。

然而,你可以在实现文件中包含Objective-C。

(.mm或者你可以在文件信息中设置如何解释.cpp文件。选择Info->General:FileType:Sourcecode.cpp.objcpp)

使用:

cppClass.h:

class objcClass;

objcClass* mMemberVariable;

cppClass.mm:

#import "objcClass.h";

void cppFunction(){
    [objcClass message];
}

在cpp头文件中。

然后在.cpp或.mm文件中包含定义该类的头文件。


你可以在C++头文件中使用Objective-C,我正在开发一个这样的项目。实现方式是在“工具”->“文件检查器”中将其设置为Objective-C++,而头文件中的obj-c代码则被包含在#if defined(OBJC)中。 - rich.e
我发现如果文件不是.mm文件,就不能在头文件中声明任何Objective-C类。在我的情况下,由于我的代码需要跨平台,我将所有的Objective-C类都声明为void*,然后在.mm实现文件中进行强制类型转换。 - Adamski

1
如果您使用Qt,可以使用Q_FORWARD_DECLARE_OBJC_CLASS宏来前向声明Objective-C类。
作为参考,这是实现方法:
#ifndef Q_FORWARD_DECLARE_OBJC_CLASS
#  ifdef __OBJC__
#    define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname
#  else
#    define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname
#  endif
#endif

0

我使用了一种名为“根据编程语言扩展文件”的技术。此外,我在编译器中添加了“-x objective-c ++”,但问题仍然存在。我得到了链接的建议,注意“文件类型”参数。


0
在XCode 11中,可以通过更改生成设置的“编译源代码”(GCC_INPUT_FILETYPE)为“Objective-C ++”(sourcecode.cpp.objcpp)来完成。这样做,就不需要将文件扩展名更改为mm。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接