C与C++在Linux下的集成问题
来源:互联网 发布:autocad mac 中文版 编辑:程序博客网 时间:2024/05/16 04:05
本文转自 http://www.qqread.com/cpp/p397124.html
最近遇到一个挺挠头的技术问题,我们波士顿那边客户公司的代码是既有C++又有C,我们作为外包公司,需要把我们的C++代码与他们的集成起来,原先的集成方案是我们的C++与他们的C++揉在一起,这样不Touch任何C集成的冬冬,我当时在波士顿已经搞定了此问题,但出差回来前客户提出要优化系统效率,其意思就是想让我们更多地重用他们的C代码,这样集成C与C++的任务逐渐提上日程。
网上有很多讨论这方面的中英文文章,但感觉不是很全面,等我使用这些方法搞不定时,没有提供一个全面系统的分析解决问题的思路,我摘选了其中一篇:http://www.pconline.com.cn/pcedu/empolder/gj/c/0508/693175_3.html,文章有四个部分,前三个部分属于科普,可以不看,最后一个部分讲述了C++调用C和C调用C++的两个范例,甚是有用,我总结一下:
(1)C++调用C的问题:
在C++的File中,加入C的头文件,一般情况下需要加extern "C", 但这点不是铁律,后面我会专门讲这个问题,认定这点有时会死得比较惨。建议原文范例中增加__cplusplus宏比较好一些,例如:
#if defined(__cplusplus)extern "C"{#endif#include "cExample.h" //头文件声明#if defined(__cplusplus)}#endif
加extern "C"的原因是因为C++在编译函数名时加入了很多其他怪异字符,这点是C++语言为了支持重载overload的特性以及其它特性所不得不加的冬冬,但C是朴素型,编译出来的符号表就是代码里的函数名。加了extern C后,编译器就会按照C的命名方式将C++引用C代码的地方使用C方式的函数名,避免引用和定义出现命名的不一致。但有一个问题是这一点取决于特定的编译器,而不是绝对的,我在.NET的VC7下拿我们的工程做了个试验没有问题,但在Linux的g++下就歇了,原因是什么?Window下的nmake在编译时使用的原则是:C代码按照C的命名方式编译引用点和函数定义,可是g++就是另外一回事了,它对C的代码采取的是C++的命名方式,怎么印证这个问题呢,下面我来介绍一下Linux下的两个工具nm和objdump, 命令如下:
objdump -x (Obj文件名) , nm (Obj文件名)
下面给出更详尽的测试依据,例如C代码中的PP__sctp函数在g++编译后的符号表就变了
nm mylib.a |grep PP__sctp结果是:U _Z8PP__sctpPKcmm000000c0 B V__PP__sctp00000040 T _Z8PP__sctpPKcmm
看到了吧!U是引用点的函数符号,T的定义点的函数符号,如果你在调用时加了extern "C",编译后,肯定会有一条错误说:undefined reference "PP__sctp".
这就是我要讲的第一个问题,C,C++集成编译时需要看具体的编译环境和工具,充分利用你手头的工具帮你来分析和定位问题。
(2)C调C++的问题
具体可以参看前面说的文章,非常有用,要点是:C调用C++,通过extern 变量或函数的外部声明,而不用include头文件方式。但前面提到的第一个问题依然会在不同的编译器下重演,你需要定位分析,看是否需要加extern "C",只要耐心一些,就会快速定位和解决问题。
我这里提到的第二个问题是在复杂工程下会出现的问题,我们的工程巨大,六千多个文件,和我们相关的就有7,8百个,最后在链接时,出了问题是几个静态库互相引用,打成了死结,因为g++ 通过-l选项加入库的顺序也是有讲究的,先引用的库可以使用后引用库的函数和变量,但反过来则不行。
这里介绍一个办法,利用拓扑分析,把几个库的引用关系用圈和箭头表示出来,就像分析最短路径那样,如果发现是个环状拓扑,只管把它们加入到一个库中即可,当然这是在Linux下,Windows下我不Sure是否会出现类似问题。
昨天晚上在家里用VPN连到单位忙到12点才搞定,白天也多亏几位同事的帮助才有了思路,呵呵,解决了问题就是爽啊。
- C与C++在Linux下的集成问题
- C与C++在Linux下的集成问题
- C与C++在Linux下的混合编译问题zz
- C语言库函数的调用问题 ,在linux下编译
- linux下c的集成开发工具IDE--eclipse+cdt
- linux下c的集成开发工具IDE--eclipse+cdt
- Linux下安装eclipse的C/C++集成开发环境
- python与c的集成
- python与c的集成
- perl与C和C++集成的问题
- Oracle在Linux下的C开发
- lua c在linux下的编译
- Linux下的c编程 出现问题
- linux下C语言编译的问题
- Linux下C语言编程的问题
- jnative在linux下对c程序的动态链接库的调用问题及解决方案
- 在linux 下编译c程序时“ error:dereferencing pointer to incomplete type”的问题
- 关于在ARM中(MDK下)C与汇编混合编程的问题
- 多业务安全路由器网关走俏的原因
- 生成一定范围的随机数
- 爱立信笔试
- OverLoading and Scope
- getRecentTasks过程
- C与C++在Linux下的集成问题
- qsort函数简介
- hadoop管理NameNode AND SecondaryNameNode
- Linux下的段错误产生的原因及调试方法
- JavaScript 确认框 confirm
- Android 左右滑动切换页面或Activity的效果实现
- HTML5之CANVAS 用法示例汇总
- 123
- ubuntu之——用户管理