Iphone 包装一个C++;Objective-C中的库没有隐藏C++;象征

Iphone 包装一个C++;Objective-C中的库没有隐藏C++;象征,iphone,c++,objective-c,xcode,xamarin.ios,Iphone,C++,Objective C,Xcode,Xamarin.ios,我试图用ObjuleC包装一个C++库(Sybase ULALITE),这样库可以被导入MonoTouch。我创建了一个Objto-C库,并在这个项目里包含了编译的C++库,LBURBR.A。要使我的项目编译,我将路径设置为用户标题搜索路径,指向C++头文件所在的目录。然后我不得不将编译源代码设置为Objective-C++ 现在的问题是,尽管包装器库编译正确,但一旦我将其包含在另一个Xcode项目中,我必须再次将编译源设置为Objective-C++,否则使用我的包装器库的项目会产生链接错误。

我试图用ObjuleC包装一个C++库(Sybase ULALITE),这样库可以被导入MonoTouch。我创建了一个Objto-C库,并在这个项目里包含了编译的C++库,LBURBR.A。要使我的项目编译,我将路径设置为用户标题搜索路径,指向C++头文件所在的目录。然后我不得不将编译源代码设置为Objective-C++

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

编译使用我的包装器的项目时出现的链接错误如下: (由于错误列表很长,我已对其进行了删节!)

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

#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 
#导入
@接口数据访问:NSObject{}
//释放对象。
-(无效)解除锁定;
//DataAccess类的单例实例。
+(数据访问*)共享状态;
//完成数据库管理后,完成数据库管理器。
+(无效)fini;
//将给定名称添加到数据库中。
-(void)addName:(NSString*)名称;
@结束

<> P>任何人都知道如何编译为ObjultC++,但仍然有一些项目使用这个库,请将其视为Objtovi-C?

< P>看起来你需要静态连接C++运行库和包装库来真正解决这个问题。我想如果图书馆的客户使用ObjuleC++,你会遇到问题,你在同一个程序中最终有两个C++标准库版本。

一个MaCOS项目的快速测试似乎表明,你需要将C++库类型设置为“静态”,也可以设置“默认隐藏的符号”。p> 您必须将包装器构建为共享对象,而不是静态库。静态库不链接,函数的解析(具体是由您包裹的代码所使用的C++标准库函数)在链接时发生。

< P> @ Mark Bessey在这里是正确的,但是他不正确地设置语言和添加C++库之间的差别不大。添加C++库是廉价的(需要一种或那种方式)。更改语言代价很高,因为ObjC++编译器速度较慢,而根据我的经验,在gdb中通过Xcode处理生成的代码有点麻烦


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

Hi Mark。谢谢你的回答。您所说的需要静态地运行C++运行库的话似乎是有道理的。只是我对Objective C和Xcode非常陌生,不知道要在链接器标志中添加什么标志来实现这一点。如果你能让我知道我将如何做这件事,我会尝试一下。使用Objective-C++的客户端的问题根本不是问题,因为在我的例子中,客户端是MonoTouch btouch工具,它只适用于Objective-C。设置默认隐藏的符号通常是很好的卫生措施,但我不认为这是解决此问题的一部分。他的问题是他找不到符号,不是太多的符号可见。这是iPhone,所以他不能使用共享库。在Mac上,他只应该不使用共享库。bundle中的共享库带来了很多麻烦,并且增加了bundle的大小(因为您不能去除死代码)。根据我的经验,如果您不在程序之间共享代码,静态库是首选的。@Rob:好吧,除非Mac与其他版本的BSD非常不同,否则所需的函数不会成为他的静态包装库的一部分,因为它没有链接。因此,客户需要提供它们。在VisualC++中,我可以做<代码> >语法>注释(LIB,LIBNEX)<代码>自动链接到前提库,苹果编译器有什么相似的吗?在MAC(和BSD)上,静态库只是捆绑在一起的。因此,您需要在应用程序的最终链接中列出所有其他库(与动态库不同,动态库可以包含对其自身依赖项的引用)。在本例中,可以通过传递-lstdc++来实现。不幸的是,没有与您列出的
#pragma
等价的东西。问题是关于iPhone,它在任何情况下都不支持第三方共享库。@Rob:动态库是通过链接创建的,所以它们通常不“包含对自身依赖项的引用”,而是包含依赖项(除非依赖项本身是一个共享库,但这里的每个人都在谈论静态libstdc++)。我要向你们在iPhone上的专业知识低头……我没有,也不是为一个而开发,我只是试图根据苹果当前操作系统的BSD遗产推断行为。“只是一堆对象文件”是对所有主要平台上静态库的一个很好的描述。此外,为了链接器的效率,通常还有一个符号目录,但这并不能从根本上改变行为。我删除了第一段,因为它的措辞不恰当。鉴于Bruce希望有一个库而不挂起对libstdc++的引用,他需要使用e静态版本。请参阅我编辑的响应
#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