简体   繁体   English

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

[英]Wrapping a C++ library in Objective-C is not hiding the C++ symbols

I am trying to wrap a C++ library (for Sybase Ultralite) with Objective-C so that the library can be imported into MonoTouch. 我正在尝试使用Objective-C包装C ++库(用于Sybase Ultralite),以便可以将库导入MonoTouch。 I have created an Objective-C library and included the compiled C++ library in this project, libulrt.a . 我创建了一个Objective-C库,并在此项目libulrt.a中包含了已编译的C ++库。 To get my project to compile I set the path to the User Header Search Path to point to the directory where the C++ header files are located. 为了让我的项目进行编译,我将用户头搜索路径的路径设置为指向C ++头文件所在的目录。 I then had to set compile source as to Objective-C++ . 然后,我必须设置Objective-C ++的 编译源 代码

The problem now is that, although the wrapper library compiles correctly, once I include it in another Xcode project I have to again set compile source as to Objective-C++ otherwise the project consuming my wrapper library gives linking errors. 现在的问题是,虽然包装器库正确编译,但是一旦我将它包含在另一个Xcode项目中,我必须再次设置编译源代码Objective-C ++,否则使用我的包装器库的项目会产生链接错误。 I don't understand why this is, because the header file for my wrapper library contains only Objective-C code and not C++ code at all. 我不明白为什么会这样,因为我的包装器库的头文件只包含Objective-C代码而不包含C ++代码。 C++ code is only found in the implementation (*.mm file) of the wrapper library. C ++代码只能在包装器库的实现 (* .mm文件)中找到。 What do I need to do to make the C++ implementation completely transparent to the project consuming the wrapper library? 我需要做些什么才能使C ++实现对使用包装器库的项目完全透明? In other words, I want to be able to include my wrapper library and compile with compile source as set to Objective-C . 换句话说,我希望能够包含我的包装器库并使用编译源编译为 Objective-C Anyone got any ideas how to do this? 任何人有任何想法如何做到这一点?

The linking errors that I am getting when compiling the project consuming my wrapper are as follows: (I have abridged the error listing because it is LONG!) 我在编译使用我的包装器的项目时遇到的链接错误如下:(我已经删除了错误列表,因为它很长!)

"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)

The header file for my wrapper library is as follows: 我的包装器库的头文件如下:

#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 

Anyone have any idea how I can compile this as Objective-C++ but still have the projects consuming this library see it as Objective-C? 任何人都知道如何编译它作为Objective-C ++,但仍然有使用此库的项目将其视为Objective-C?

@Mark Bessey is on the right track here, but he's incorrect that there is little difference between setting the language and adding the C++ library. @Mark Bessey在这里是正确的轨道,但他的错误是设置语言和添加C ++库之间没有什么区别。 Adding the C++ library is cheap and required (one way or another). 添加C ++库既便宜又需要(以这种或那种方式)。 Changing the language is expensive because the ObjC++ compiler is slower, and the resulting code is in my experience a bit of a pain to deal with in gdb through Xcode. 更改语言是昂贵的,因为ObjC ++编译器速度较慢,并且由此产生的代码在我的经验中通过Xcode处理gdb有点痛苦。

All you should need is to add -lstdc++ to your LD_FLAGS (Other Linker Flags) in your consuming project. 您只需要在消费项目中将-lstdc ++添加到LD_FLAGS(其他链接器标志)中。 Do make sure that "C++ Standard Library Type" is set to Dynamic. 确保将“C ++标准库类型”设置为“动态”。

Seems like you'd need to statically link the C++ runtime library with your wrapper library to really get around this. 好像你需要静态地将C ++运行时库与你的包装器库链接起来才能真正解决这个问题。 I think then you might run into problems if a client of the library used Objective-C++, and you ended up with two versions of the C++ standard library in the same program. 我认为如果库的客户端使用Objective-C ++,你可能会遇到问题,并且你在同一个程序中最终得到了两个版本的C ++标准库。


A quick test with a MacOS project seems to indicate that you need to set the C++ library type to "static", and maybe set "symbols hidden by default" also. 使用MacOS项目的快速测试似乎表明您需要将C ++库类型设置为“静态”,并且还可以设置“默认情况下隐藏的符号”。

You'll have to build your wrapper as a shared object, not a static library. 您必须将您的包装器构建为共享对象,而不是静态库。 A static library is not linked, resolution of functions (and specifically the C++ standard library functions used by the code you are wrapping) happens at link time. 静态库没有链接,函数的解析(特别是你正在包装的代码使用的C ++标准库函数)在链接时发生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM