在Objective-C中包装C ++库并不是隐藏C ++符号

时间:2011-03-15 13:15:51

标签: iphone c++ objective-c xcode xamarin.ios

我正在尝试使用Objective-C包装C ++库(用于Sybase Ultralite),以便可以将库导入MonoTouch。我创建了一个Objective-C库,并在此项目中包含了已编译的C ++库 libulrt.a 。为了让我的项目进行编译,我将用户头搜索路径的路径设置为指向C ++头文件所在的目录。然后我必须将编译源代码设置为 Objective-C ++

现在的问题是,尽管包装器库正确编译,但是一旦我将它包含在另一个Xcode项目中,我必须再次编译源代码设置为 Objective-C ++ 否则使用我的包装器库的项目会产生链接错误。我不明白为什么会这样,因为我的包装器库的头文件只包含Objective-C代码而不包含C ++代码。 C ++代码只能在包装器库的 implementation (* .mm文件)中找到。我需要做些什么才能使C ++实现对使用包装器库的项目完全透明?换句话说,我希望能够包含我的包装器库并使用编译源代码设置为 Objective-C 进行编译。任何人有任何想法如何做到这一点?

编译使用我的包装器的项目时,我得到的链接错误如下: (我已经删除了错误列表,因为它很长!)

"operator delete(void*)", referenced from:
zc3db40339fee::~zc3db40339fee()in libUltralite.a(ee39bf4763.o)
zb4297ee7d543::~zb4297ee7d543()in libUltralite.a(747e80fdad.o)
z33836a0a6f46::~z33836a0a6f46()in libUltralite.a(f240efda30.o)
"___cxa_pure_virtual", referenced from:
vtable for ze78b0ec59364in libUltralite.a(2c50e8e8ff.o)
vtable for ze78b0ec59364in libUltralite.a(2c50e8e8ff.o)
vtable for ze78b0ec59364in libUltralite.a(2c50e8e8ff.o)

我的包装器库的头文件如下:

#import <Foundation/Foundation.h>

@interface DataAccess : NSObject {}

// Release objects.
- (void)dealloc;

// Singleton instance of the DataAccess class. 
+ (DataAccess*)sharedInstance; 

// Finalize the Database Manager when done with the DB.
+ (void)fini;

// Adds the given name to the database. 
- (void)addName:(NSString *)name;
@end 

任何人都知道如何将其编译为Objective-C ++,但仍然使用此库的项目将其视为Objective-C?

3 个答案:

答案 0 :(得分:6)

@Mark Bessey在这里是正确的轨道,但他说错了,设置语言和添加C ++库之间没有什么区别。添加C ++库既便宜又需要(以这种或那种方式)。更改语言是昂贵的,因为ObjC ++编译器速度较慢,并且通过Xcode在gdb中处理生成的代码对我来说有点痛苦。

您只需要在消费项目中将-lstdc ++添加到LD_FLAGS(其他链接器标志)中。确保将“C ++标准库类型”设置为“动态”。

答案 1 :(得分:1)

好像你需要静态地将C ++运行时库与你的包装器库链接起来才能真正解决这个问题。我认为如果库的客户端使用Objective-C ++,你可能会遇到问题,并且你在同一个程序中最终得到了两个版本的C ++标准库。


使用MacOS项目的快速测试似乎表明您需要将C ++库类型设置为“静态”,并且也可以设置“默认情况下隐藏的符号”。

答案 2 :(得分:1)

您必须将包装器构建为共享对象,而不是静态库。静态库没有链接,函数的解析(特别是你要包装的代码使用的C ++标准库函数)在链接时发生。