c和c++相互调用

    xiaoxiao2022-06-29  63

    extern "C"的惯用法   (1)在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)时,需进行下列处理:         extern "C"        {         #include "cExample.h"                                         }   而在C语言的头文件中,对其外部函数只能指定为extern类型,C语言中不支持extern "C"声明,在.c文件中包含了extern "C"时会出现编译语法错误。   笔者编写的C++引用C函数例子工程中包含的三个文件的源代码如下:                     #ifndef C_EXAMPLE_H       #define C_EXAMPLE_H        extern int add(int x,int y);       #endif

                #include "cExample.h"      int add( int x, int y )      {             return x + y;      }      // c++实现文件,调用add:cppFile.cpp      extern "C"       {      #include "cExample.h"      }      int main(int argc, char* argv[])      {             add(2,3);              return 0;       }

          如果C++调用一个C语言编写的.DLL时,当包括.DLL的头文件或声明接口函数时,应加extern "C" { }

         (2)在C中引用C++语言中的函数和变量时,C++的头文件需添加extern "C",但是在C语言中不能直接引用声明了extern "C"的该头文件,应该仅在C文件中将C++中定义的extern "C"函数声明为extern类型。   笔者编写的C引用C++函数例子工程中包含的三个文件的源代码如下:

            //C++头文件 cppExample.h         #ifndef CPP_EXAMPLE_H         #define CPP_EXAMPLE_H         extern "C" int add( int x, int y );         #endif         //C++实现文件 cppExample.cpp         #include "cppExample.h"         int add( int x, int y )         {                 return x + y;         }                 extern int add( int x, int y );        int main( int argc, char* argv[] )       {              add( 2, 3 );               return 0;        }

      如果深入理解了第3节中所阐述的extern "C"在编译和连接阶段发挥的作用,就能真正理解本节所阐述的从C++引用C函数和C引用C++函数的惯用法。对第4节给出的示例代码,需要特别留意各个细节。 对于以上C++调用C语言函数会出现以下现象:

    这样编译会产生错误cpp.obj : error LNK2001: unresolved external symbol "int __cdecl add(int,int)" (?add@@YAHHH@Z),原因是找不到add的目标模块

    这才令我想起C++重载的函数命名方式和C函数的命名方式,让我们回顾一下:C中函数编译后命名会在函数名前加以"_",比如add函数编译成obj文件时的实际命名为_add,而c++命名则不同,为了实现函数重载同样的函数名add因参数的不同会被编译成不同的名字

    例如

    int add(int , int)==>add@@YAHHH@Z,

    float add(float , float )==>add@@YAMMM@Z,

    以上是VC6的命名方式,不同的编译器会不同,总之不同的参数同样的函数名将编译成不同目标名,以便于函数重载是调用具体的函数。

    编译cpp.cpp中编译器在cpp文件中发现add(1, 0);的调用而函数声明为extern int add(int x, int y);编译器就决定去找add@@YAHHH@Z,可惜他找不到,因为C的源文件把extern int add(int x, int y);编译成_add了;

    为了解决这个问题C++采用了extern "C",这就是我们的主题,想要利用以前的C程序库,那么你就要学会它,我们可以看以下标准头文件你会发现,很多头文件都有以下的结构

    #ifndef __H #define __H #ifdef __cplusplus extern "C" { #endif extern int f1(int, int); extern int f2(int, int); extern int f3(int, int); #ifdef __cplusplus } #endif #endif /*__H*/

    如果我们仿制该头文件可以得到

    #ifndef _C_H_ #define _C_H_ #ifdef __cplusplus extern "C" { #endif extern int add(int, int); #ifdef __cplusplus } #endif #endif /* _C_H_ */

    这样编译

    /*-----------c.c--------------*/ int add(int x, int y){ return x+y; }

    转载请注明原文地址: https://ju.6miu.com/read-1125084.html

    最新回复(0)