C 与 C++互相调用函数,变量
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