博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C与C++在Linux下的集成问题
阅读量:4036 次
发布时间:2019-05-24

本文共 1754 字,大约阅读时间需要 5 分钟。

最近遇到一个挺挠头的技术问题,我们波士顿那边客户公司的代码是既有又有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宏比较好一些,例如:

QUOTE:
#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++编译后的符号表就变了

QUOTE:
nm mylib.a |grep PP__sctp
结果是:
U _Z8PP__sctpPKcmm
000000c0 B V__PP__sctp
00000040 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下,下我不Sure是否会出现类似问题。
昨天晚上在家里用连到单位忙到12点才搞定,白天也多亏几位同事的帮助才有了思路,呵呵,解决了问题就是爽啊。

转载地址:http://ulcdi.baihongyu.com/

你可能感兴趣的文章
Maven项目版本继承 – 我必须指定父版本?
查看>>
Maven跳过单元测试的两种方式
查看>>
通过C++反射实现C++与任意脚本(lua、js等)的交互(二)
查看>>
利用清华镜像站解决pip超时问题
查看>>
[leetcode BY python]1两数之和
查看>>
微信小程序开发全线记录
查看>>
Centos import torchvision 出现 No module named ‘_lzma‘
查看>>
PTA:一元多项式的加乘运算
查看>>
CCF 分蛋糕
查看>>
解决python2.7中UnicodeEncodeError
查看>>
小谈python 输出
查看>>
Django objects.all()、objects.get()与objects.filter()之间的区别介绍
查看>>
python:如何将excel文件转化成CSV格式
查看>>
Django 的Error: [Errno 10013]错误
查看>>
机器学习实战之决策树(一)
查看>>
机器学习实战之决策树二
查看>>
[LeetCode By Python]7 Reverse Integer
查看>>
[leetCode By Python] 14. Longest Common Prefix
查看>>
[leetCode By Python]111. Minimum Depth of Binary Tree
查看>>
[LeetCode By Python]118. Pascal's Triangle
查看>>