iPhone调用MAC OS X上C/C++写的.dylib问题(一)

Author 正正 Date 2011.03.02 10:19:00   转载请注明出处 正正博客 http://www.2009fly.com

刚刚入门,有不正确之处还望指正!

本来以为iPhone可以直接调用MAC OS X 上的BSD C library(.dylib),结果用otool工具查看到新建立的libHelloC.dylib,得到如下结果:

$ otool -L libHelloC.dylib

libHelloC.dylib:

/usr/local/lib/libHelloC.dylib (compatibility version 1.0.0, current version 1.0.0)

/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)

而对于建立的iPhone工程 View based Application程序:

$ otool -L HelloWorld

HelloWorld:

/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 751.49.0)

/System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 1400.0.0)

/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics (compatibility version 64.0.0, current version 600.0.0)

/usr/local/lib/libHelloC.dylib (compatibility version 1.0.0, current version 1.0.0)

/usr/lib/libSystem.dylib (compatibility version 1.0.0, current version 125.0.0)

/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 550.52.0)

/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)

看到一个是/usr/lib/libSystem.dylib,另一个是/usr/lib/libSystem.B.dylib,于是在网上搜索到:

http://stackoverflow.com/questions/3313786/ios-4-app-crashes-at-startup-on-ios-3-1-3-symbol-not-found-nsconcretestackblo

看到如下解释:

Clint Harris提问:I’m running Xcode 3.2.3 with the iOS 4.0 SDK. I built my app with Base SDK = iphoneos4.0, Active SDK = iphoneos4.0, Deployment Target = 3.1.3, and Architecture = standard (arm6 arm7). Compiler = GCC 4.2. As I understand it, this is the correct way to build an app for both iOS 4 and 3.

The app runs fine on devices running iOS 4. But it crashes on startup when you try to run it on a device with iOS 3.1.3 (an iPod Touch 1G):

dyld: Symbol not found: __NSConcreteStackBlock
Referenced from: /var/mobile/Applications/192B30ED-16AC-431E-B0E9-67C1F41FD5DA/MyApp.app/MyApp
Expected in: /usr/lib/libSystem.B.dylib

Brad Larson回 答:Ben Gottlieb pointed out yesterday that if you use blocks anywhere in your application, you’ll see a crash similar to this on a pre-4.0 OS while building with the LLVM compiler. To work around this, you can specify the linker flag -weak_library /usr/lib/libSystem.B.dylib in your Xcode build settings.

下面是一些交互讨论:

Ah, thanks Brad! I was just coming back to share the same solution (after some trial and error)… For anyone else who might come across this and need help setting up the weak link, here’s a screenshot:

快照截图

Also, note that it doesn’t seem to be specific to the LLVM compiler–I’m just using GCC 4.2. – Clint Harris Jul 22 ’10 at 22:45

@Clint Harris – I think for the LLVM compiler you still need to force the weak-linking using the compiler flag, because it doesn’t respect the setting within Xcode’s project window there. – Brad Larson Jul 22 ’10 at 22:49

What does “block” mean in this context? Block to me means a block of code, which I suppose is hardly what you mean here. This solution did fix it for me too btw. Thanks a lot! – quano Jul 25 ’10 at 2:47

@quano – A block is a new C language construct introduced in Snow Leopard and iOS 4.0. See here for a good introduction to them: developer.apple.com/iphone/library/featuredarticles/… – Brad Larson Jul 25 ’10 at 3:48

Odd, I’m not using any of those, and all my libraries I’m using are working with iPhone OS 3, so I don’t understand why it would require me to specify linker flags for things I’m not even using. Oh well, I’m just happy it works. Thanks again. – quano Jul 25 ’10 at 4:33

我建议,最好不要这么调用,因为iPhone与MaxOS X上的库的链接位置可能不同,建议参考2009FLY网摘的下面几个网址:

【提示:你可以自己构造自己的tool chain工具链来做类似的开发!】

1、  修改Xcode配置使其支持创建编译iphone上的dylib工程

http://www.2009fly.com/index/a/yidongkaifa/iPhone/rumen/iPhonegaoji/2011/0225/551.html

2、  Mac OS X 如何执行应用程序

http://www.2009fly.com/index/a/yidongkaifa/iPhone/rumen/iPhonegaoji/2011/0228/603.html

3、  XCode、Cocoa开发中使用第三方dylib的方法

http://www.2009fly.com/index/a/yidongkaifa/iPhone/rumen/iPhonegaoji/2011/0225/552.html

4、在Leopard中编译搭建非官方iPhone toolchain开发环境并整合到XCode

http://www.2009fly.com/index/a/yidongkaifa/iPhone/iPhonejinjie/2011/0302/661.html

下面是apple官方的文档,仅供参考:

http://www.apple.com.cn/developer/mac/library/documentation/DeveloperTools/Conceptual/CppRuntimeEnv/Articles/CPPROverview.html

C++运行环境概述

在Mac OS X 10.3.9之前,标准C++库被封装为静态档案文件libstdc++.a。而在10.3.9及之后的系统上,标准C++库则被封装为动态共享库,文件 名为libstdc++.dylib。这个封装上的变化使C++的运行环境和C的运行环境达成一致,一直以来,C的运行环境都被封装为动态共享库 libSystem.dylib的一部分。

请注意:如果您要连编与libstdc++.dylib相连接的程序,必须使用GCC 4.0,该编译器由Mac OS X 10.4中的Xcode开发工具提供。您可以将这个编译器和苹果提供的SDK一起使用,为Mac OS X 10.3.9连编二进制代码。更多的信息请参见“部署基于libstdc++.dylib的应用程序”

本部分包括如下内容:

共享C++运行环境的优势
二进制兼容性

共享C++运行环境的优势

将标准C++库封装为动态共享库对于保证程序的性能和正确性是很重要的。如果您的执行文件需要连接libstdc++.a和几个其它的动态共享库,而那些动态共享库中有一个或者一个以上也连接到libstdc++.a,则在运行时会有多个库的拷贝被装载到内存中。

为了程序的正确性,所有的构件应该使用完全相同的标准C++连接库的拷贝。这是因为某些C++运行环境的数据必须在所有的构件中共享,否则可能 会发生意料不到的结果。举例来说,如果有两个构件同时使用C++的I/O机制来向标准输出进行写操作,如果它们使用不同的缓冲区,则结果可能会被修改。

从性能的角度上看,由于每个拷贝都要被读入内存,而同一连接库的多个拷贝会使磁盘的访问量增加。而且额外的拷贝会加大应用程序的内存印迹,因而可能 导致内存页面交换及缓存机会错失的可能性增加。消除重复的库可以显著减少应用程序的印迹。作为例子,我们考虑下面这个用libstdc++.a和GCC 3.3 编译完成的“hello world”程序:


int main ()
{
std::cout << “Hello, World!\n” << std::endl;
return 0;
}

在Mac OS X v10.4系统上,上述程序的结果文件尺寸是650 KB,而同样的程序在同样的系统上用GCC 4.0和libstdc++.dylib进行编译,结果是17 KB。

二进制兼容性

GCC 4.0遵循Itanium C++ ABI,它是一个编译完成的C++代码标准。该标准规范的维护者是一个由多厂商组成的协会,规范内容涵盖诸如名称重整(name mangling),类成员布局,虚函数调用协议,例外处理,以及运行时类型信息(RTTI)格式这样的问题。您可以在http://www.codesourcery.com/cxx-abi/abi.html站点上找到该规范的最新版本。

由于GCC 4.0遵循Itanium C++ ABI,所以C++对象可以和Mac OS X上同样遵循该规范的其它编译器连编而成的对象相互连接。苹果保证未来的Mac OS X GCC发行版也遵循Itanium C++ ABI。这意味着开发者可以安全地发行包含C++类接口的动态共享库,只是需要注意如下的事项:

苹果电脑只保证核心语言特性部分的ABI的稳定性,而不保证连接库中类的稳定性,其中包括std::string,std::map<T>,和std::ostream。

苹果不保证不同的libstdc++大版本之间的二进制兼容性。GCC 4.0和该连接库的6.0.3版一起发行,如果将来发布新的大版本(版本7.0.0),则该库并不保证和6.x版本互相兼容。

第三方的动态共享库的不同版本之间的二进制兼容性也依赖于库的设计,而不仅仅依赖于编译器对标准ABI的支持。您必须确保不引入兼容性的问题。

如果您正在设计一个准备分发给不通用户的动态共享库,则仍然有义务确保自己不产生二进制兼容性问题。例如,您不应该在基类中引入成员变量或者虚函数,这种做法会使基类变得脆弱,并使库的客户程序需要重新编译。

更多二进制兼容性问题的信息,请参见“创建兼容的连接库”

====================================================================

版权所有,欢迎转载,请在转载前注明原文出处:正正博客 http://www.2009fly.com

尊重别人的劳动成果也就是尊重自己!

推荐:2009FLY文摘|正正博客

====================================================================

posted @ 2011-03-27 12:36  zzc1986  阅读(3029)  评论(3编辑  收藏  举报