C 与 C++互相调用函数,变量

时间:2022-09-29 11:53:13
1. C 调用C++
// C++头文件,example.h
extern "C" void Print(int i);
extern "C" int g_num;

// C头文件,example_c.h
void Print_C(int i);
extern int g_num_c;

//C++文件,example.cpp
#include <iostream>
#include "example.h"
void Print(int i)
{
std::cout<<"This is a function defined in C++,variable defined in a c++ file:"<<i<<std::endl;
}

int g_num = 1;

//C文件,example_c.c
#include <stdio.h>

void Print_C(int i)
{
printf("This is a function defined in C,variable defined in a c file:%d\n",i);
}

int g_num_c = 0;

extern void Print(int i);
extern int g_num;
void main()
{
printf("C call C++\n");
Print(g_num);
printf("C call C\n");
Print_C(g_num_c);
}
 
 结果:

C call C++
This is a  function defined in C++,variable defined in a c++ file:1
C call C
This is a  function defined in C,variable defined in a c file:0

C 调用C++的函数或变量,在C++的头文件声明为extern "C" ,C调用的时候只使用extern 声明。

查看目标文件:

D:\workspace\HEVC\C++vsC\C_C++_call>dumpbin  /RELOCATIONS example_c.obj
Microsoft (R) COFF Binary File Dumper Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file example_c.obj

File Type: COFF OBJECT

RELOCATIONS #2
                                                Symbol    Symbol
Offset    Type              Applied To         Index     Name
--------  ----------------  -----------------  --------  ------
000000AA  SECREL                     00000000         C  _Print_C
000000AE  SECTION                        0000         C  _Print_C
000000EB  SECREL                     00000000        17  _main
000000EF  SECTION                        0000        17  _main
00000103  SECREL                     00000000         9  _g_num_c
00000107  SECTION                        0000         9  _g_num_c
00000119  SECREL                     00000000        1B  _g_num
0000011D  SECTION                        0000        1B  _g_num

symbol为函数变量名前加_ .

 

dumpbin  /RELOCATIONS example.obj>2.txt  可以看到C++中使用了extern "C"声明,目标文件中的symbol也是_g_num ,_Print.

 

如果注释掉example.cpp 中#include "example.h"

example_c.obj : error LNK2001: unresolved external symbol _Print
example_c.obj : error LNK2001: unresolved external symbol _g_num

出现链接错误,dumpbin  /SYMBOLS example.obj>2.txt,C++的链接规则生成的symbol为 ?g_num@@3HA (int g_num),?Print@@YAXH@Z (void __cdecl Print(int)).

可见,extern "C"告诉了C++的编译器,使用C的链接规则生成和寻找目标文件中的symbol名称。

 

 

 

2.  C++ 调用C

//C++文件,example.cpp
#include <iostream>
//#include "example.h"
void Print(int i)
{
std::cout<<"This is a function defined in C++,variable defined in a c++ file:"<<i<<std::endl;
}

int g_num = 1;
extern "C"
{
#include "example_c.h"
}

void main()
{
std::cout<<"C++ call C"<<std::endl;
Print_C(g_num_c);
std::cout<<"C++ call C++"<<std::endl;
Print(g_num);
}

结果:

C++ call C
This is a  function defined in C,variable defined in a c file:0
C++ call C++
This is a  function defined in C++,variable defined in a c++ file:1

 

查看目标文件:

dumpbin  /SYMBOLS example.obj>2.txt , symbol为:_Print_C , _g_num_c ;?Print@@YAXH@Z (void __cdecl Print(int)),?g_num@@3HA. (int g_num)

 

总之 extern "C" {  } ,声明用于C++中,告诉编译器对{ }中声明的函数或变量使用C的方式生成(或寻找)目标符号。

 

3. C++ 调用C中的内联函数

   C中的函数使用__inline声明为内联函数时,不会链接生成目标符号。

   example_c.c中的函数改为 __inline void Print_C(int i) ,在example_c.obj找不到Print_C的符号。

  可以使用__declspec( dllexport ) __inline void Print_C(int i) 这样的声明,就会生成目标符号 External     | _Print_C 。

 

参考:msdn,Using extern to Specify Linkage ,http://msdn.microsoft.com/zh-cn/library/0603949d.aspx