如何在Objective-C中包装C ++库?

时间:2010-09-26 18:11:43

标签: c++ iphone objective-c objective-c++

我有一个C ++库(仅限.h),它包含数据结构的实现,我想在我的iPhone应用程序中使用它。

首先,我在Objective-C ++中编写了一个包装器作为一个类,通过组合,它有一个C ++类的ivar。然后我'不得不'将包装类扩展名更改为.mm,看起来很好。但是我必须将这个包装的类文件包含在其他几个文件中,所以我也必须更改它们的扩展名(为了防止编译时错误)。

我说错了吗?有没有办法将.mm扩展名“限制”为几个文件?(以防止名称冲突等)

编辑:可能有帮助的更多信息,我使用LLVM 1.5作为编译器(我注意到编译时错误的数量从GCC 4.2到LLVM 1.5不等但我不确定它意味着什么,因为我没看过他们所有人)

4 个答案:

答案 0 :(得分:4)

我的建议是在#ifdefs中包装C ++位:

//MyWrapper.h

#ifdef __cplusplus
class ComposedClass;
#endif 

@interface MyWrapper : NSObject
{
#ifdef __cplusplus
ComposedClass *ptr;
#endif
}

// wrapped methods here...
@end

这是一个略显蹩脚的PIMPL习惯版本,但代码较少,并且对于隐藏C ++而言是有效的 - 来自纯Objective-C代码的主义。很遗憾,您必须在ComposedClass中添加MyWrapper.mm标题。

如果ComposedClass是模板化类型,则需要将第一个块修改为

#ifdef __cplusplus
#include "ComposedClass.h"
#endif

而不是使用前向声明,然后,当然,在Objective-C类的实例变量声明中使用模板化类型。

此方法由Apple的运行时专家Greg Parker suggested提供。

答案 1 :(得分:4)

任何包含C ++代码段的代码(无论多小)都必须使用Objective-C ++进行编译(因此必须在.mm文件中)。如果要缩小.mm文件的数量,则必须在Objective-C类中包含C ++代码的功能,以便此类的公共接口(其.h文件)仅包含Objective-C代码。这意味着包装类不能包含C ++类型的公共ivar。如果你的C ++ lib只包含数据结构,这是否是一种可行的方法,我不知道。

请注意,AFAIK LLVM 1.5尚不包含C ++支持(仅限LLVM 2.0)。 AFAIK,当您选择LLVM 1.5时,Xcode将自动切换到GCC以获取所有C ++ / Objective-C ++文件。

答案 2 :(得分:2)

我不确定我完全理解你的问题,但我认为答案是'是'。

基本上任何需要引用包装类的东西都是Objective-C ++代码,而不是直接的C ++。

我建议您将包装类包含在实现(aka .cpp或Objective-C ++等效文件)中。它们不应该导致描述它们实现的类的头文件成为Objective-C ++。

Pimpl idiom这样的技术可以帮助您将类的用户与其部分用Objective-C ++实现的事实隔离开来。

答案 3 :(得分:1)

我首选的解决方案是这个前向声明宏:

#define FORWARD(cpp_class) struct cpp_class; typedef struct cpp_class cpp_class;

FORWARD(SomeCppClass);

@interface MyObjcWrapper : NSObject {
    SomeCppClass *ptr;
}

然后MyObjcWrapper.h可以安全地包含在Objective-C和Objective-C ++文件中。

这是我几年前看到的一篇有用的博客文章 - 现在似乎无法找到它。