您的位置:首页 > 编程语言 > C语言/C++

C/C++混合编程 —— extern "C" 的用法

2012-01-03 20:12 846 查看
2012-01-03 wcdj

Question:

What's the theory behind this: #ifdef __cplusplus extern "C" {

I have been meeting the following in some c/c++ codes but I don't understand the theory behind it:



#ifdef __cplusplus

extern "C" {

#endif



I want to understand how it works. I know about the preprocessing but I don't know what that extern "C" in the code does. Someone teach me please!

Answers 1:

The C++ compiler does something called name mangling which facilitates function overloading.

The extern "C" syntax tell the C++ compiler not to perform function overloading.

The code snippet that you posted first checks if the code being compiled is using a C++ compiler and if so starts a block in which name mangling will not be done.

Answer 2:

That typically encloses DLL's exported functions.

You should know, C Language and C++ one use different approach to function's name mangling (i.e. altering the name of the funtion in object -or library- files), more specifically, C++ includes in the mangled (or decorated) name info about the function argument
types (this allows, function overloads, a C++ feature, not available in C language).

The mechanism allows the same header to be used by both the C and C++ compiler ( __cpluspls macro is defined only by the C++ one) and works this way:

The C compiler, ignores the extern "C" (__cplusplus is not defined) directive both when building the DLL and when including the DLL header inside an application.

The C++ compiler, according with the extern "C" (__cplusplus is defined) directive:

(1) Produces a standard C DLL (i.e. the function use the C language mangling scheme) when building the DLL.

(2) consider the library as a C DLL when the header is included in a application (you know C++ compiler is able to link with C libraries).

Hope it helps.

在cpp文件中调用c文件中实现的函数的时候(考虑cpp调c,当然c也可以调cpp),需要用extern "C"声明该函数,否则cpp会按名字改编后的函数名去找该函数而找不到。

在C++中调用C的函数的一个实例:

// cFile.h
#ifndef _C_FILE_H_
#define _C_FILE_H_

extern int add(int x, int y);

#endif

// cFile.c
#include "cFile.h"

int add(int x, int y)
{
	return x+y;
}

// cppFile.h
#ifndef _CPP_FILE_H_
#define _CPP_FILE_H_

#ifdef __cplusplus
extern "C"{ 
#endif

#include "cFile.h"

#ifdef __cplusplus
}
#endif

#endif/* _CPP_FILE_H_ */

// cppFile.cpp
#include "cppFile.h"
#include <stdio.h>
/*
extern "C"
{
	#include "cFile.h"
}
*/

int main(int argc, char* argv[])
{
	printf("add = %d\n", add(2, 3));

	return 0;
}


然后对上述代码进行编译:

CC     =  gcc
CXX    =  g++
CFLAGS =  -g -Wall -Os

INCLUDE =  .
LIBPATH =
PUBLIBS =
LIBS    =  $(PUBLIBS)

BIN  =  demo
OBJS =  cppFile.o cFile.o

all: $(BIN) 

$(BIN): $(OBJS)
	$(CXX) -o $@ $^ $(LIBPATH) $(LIBS)

install:
	@echo "nothing to install"

clean:
	@-rm -f $(OBJS) $(BIN)
	@echo "clean over"


make && ./demo

在C++中可以成功调用C中定义的函数。

如果不使用extern "C"声明,则会提示如下错误:

gerryyang@mba:extern$make
g++    -c -o cppFile.o cppFile.cpp
gcc -g -Wall -Os   -c -o cFile.o cFile.c
g++ -o demo cppFile.o cFile.o  
Undefined symbols for architecture x86_64:
  "add(int, int)", referenced from:
      _main in cppFile.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [demo] Error 1
gerryyang@mba:extern$nm cFile.o
00000000000002d8 s EH_frame0
0000000000000000 T _add
00000000000002f0 S _add.eh


完整测试代码可见这里

参考:

[1] 关于 __cplusplus 的说明可以参考:C++ 2003标准,16.8 Predefined macro names

[2] 关于 extern "C" 的说明可以参考:C++ 2003标准,7.5 Linkage specifications

[2] Q&A http://www.codeproject.com/Messages/3327432/Whats-the-theory-behind-this-sharpifdef-__cplusplu.aspx
[3] extern "C"作用 http://blog.csdn.net/weiqubo/article/details/4681813
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: