面试题:C++中怎么调用C的代码

昨天参加中兴的面试,问了我这样一个问题:C++中怎么调用C的代码,直接把我问懵了,说实话,我到现在都没弄明白他要问什么,因为我平时就是混合使用C、C++的,C++不是兼容C的吗,C++难道不能直接调用C的代码吗,这个问题到底是什么意思,该怎么回答?
感谢大家热心的回答。
本人不懂编译原理,请问“帅的有点坏”朋友,你的意思是说函数库比如stdlib.h里提供的是已编译好的目标文件,而不是源文件?
我平时在C++中调用C函数库的时候也没有用 extern "C" 啊,直接包含进来就行了,比如#include<stdio.h>

1、 对于 C++ 中非类的成员函数,可以简单的在函数声明前面加 extern “C” ,通常函数声明位于头文件中,当然也可以将声明和函数定义一起放在 cpp 中 ,在没有声明的情况下,直接在定义前添加 extern “C” 也可

2、 对于 C++ 类的成员函数,则需要另外做一个 cpp 文件,将需要调用的函数进行包装 。

以上两项的实例参看前面 C 中如何调用 C++ 代码的文章。

要实现 C++ 中调用 C 的代码,具体操作:

对于 C 中的函数代码,要么将 C 代码的头文件进行修改,在其被含入 C++ 代码时在声明中加入 extern “C” 或者在 C++ 代码中重新声明一下 C 函数,重新声明时添加上 extern “C” 头 。

通过以上的说明,我明白一点,那就是加 extern “C” 头一定是加在 C++ 的代码文件中才能起作用的 。

下面分析一下这个现象的实质原因:

C 编译器编译函数时不带函数的类型信息,只包含函数符号名字,如 C 编译器把函数 int a(float x) 编译成类似 _a 这样的符号, C 连接器只要找到了调用函数的符号,就可以连接成功,它假设参数类型信息是正确的,这是 C 编译连接器的缺点。而 C++ 编译器为了实现函数重载,编译时会带上函数的类型信息,如他把上面的 a 函数可能编译成 _a_float 这样的符号为了实现重载,注意它还是没有带返回值得信息,这也是为什么 C++ 不支持采用函数返回值来区别函数重载的原因之一,当然,函数的使用者对函数返回值的处理方式(如忽略)也是重要原因。

基于以上, C 调用 C++ ,首先需要用封装函数把对 C++ 的类等的调用封装成 C 函数以便 C 调用,于是 extern "C" 的作用是:让编译器知道这件事,然后以 C 语言的方式编译和连接封装函数 (通常是把封装函数用 C++ 编译器按 C++ 方式编译,用了 extern "C" 后,编译器便依 C 的方式编译封装接口,当然接口函数里面的 C++ 语法还是按 C++ 方式编译;对于 C 语言部分 -- 调用者,还是按 C 语言编译;分别对 C++ 接口部分和 C 部分编译后,再连接就可以实现 C 调用 C++ 了 )。相反 ,C++ 调用 C 函数, extern "C" 的作用是:让 C++ 连接器找调用函数的符号时采用 C 的方式 ,即使用 _a 而不是 _a_float 来找调用函数
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-05-31
主要是用extern " C"
c++比C语言里多了模板机制与重载机制,在编译的时候会生成内部名称。例如:

int f(void,double);//生成int f_void_double(void,double);
int f(int ,long);//生成int f_int_long(int,long);

template<typename T>
int fun(void);//用int实例化就可能会出现int int_fun(void);

C语言没有这些机制,当然也没有内部名称。于是在C++的目标文件(.obj)与C语言的目标文件链接(link)的时候,就会与C++出现连接问题。
extern"C"就是指需要连接的文件,不用C++的命名方式。
第2个回答  2010-05-31
应该是调用C编译的函数之类的吧,加上
extern "C"
{
}

具体如下:
作为一种面向对象的语言,C++支持函数重载,而过程式语言C 则不支持。函数被C++编译后在symbol 库中的名字与C 语言的不同。例如,假设某个函数的原型为:void foo(int x, int y);该函数被C 编译器编译后在symbol 库中的名字为_foo,而C++编译器则会产生像_foo_int_int 之类的名字。_foo_int_int 这样的名字包含了函数名和函数参数数量及类型信息,C++就是考这种机制来实现函数重载的。为了实现C和C++的混合编程,C++提供了C 连接交换指定符号extern "C"来解决名字匹配问题,函数声明前加上extern "C"后,则编译器就会按照C 语言的方式将该函数编译为_foo,这样C 语言中就可以调用C++的函数了。解在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)时,需进行下列处理:
extern "C"
{
#include "cExample.h"
}
第3个回答  2010-05-31
--------------------------------------------------------------------
LZ,请仔细阅读我下边的一番描述,纯手写.

在C++里,想要调用C类库,比如:<stdlib.h>里的库函数qsort(),你也许会extern qsort();声明一下,然后就进行使用. 问题就出在这里, 这里要明白一些简单的编译原理了.

首先,<stdlib.h>里声明的所有函数(例如其中的qsort),它们都已经在一些Cpp文件里编译好了,是前辈们给你直接使用的函数,在最初它们被编译时,它们都是在C环境下完成的,C编译器给它们编译时会起一个函数别名,例如qsort就是C_qsort.
当你在C++类型文件中,extern qsort()以后,你认为可以直接使用了,于是你编译,连接, 想要执行,但是问题就在编译与连接部分. qsort已经被前辈们在C环境下编译过了,有了自己的名字C_qsort. 现在你在C++下,extern qsort()声明这个函数, C++编译器在编译时给它起了一个名字Cpp_qsort,然后现在要连接所有文件,找到qsort()这个函数的定义在哪里。 现在连接器相当于拿着Cpp_qsort去其他的cpp里找Cpp_qsort的定义,当然是找不到的,因为qsort()函数是以前在C环境下编译的,名字叫c_qsort.

说白了,就是C编译器与C++编译器对函数起名的方式不同. 利用extern "C"就是给C++编译器一个提示,告诉你这个函数请给我用C的方式起名,在连接时就可以找到与这个名字相符的函数,并调用了。

写这么多,希望LZ有所收获,也能追加几个分。
第4个回答  2010-05-31
extern "c"
相似回答