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 __cplusplusextern "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;}
然後對上述代碼進行編譯:
# Makefile, wcdjCC = gccCXX = g++CFLAGS= -g -Wall -ansiINCLUDE = . LIBPATH = PUBLIBS = LIBS = $(PUBLIBS)BIN_SERVER = myappOBJS_SERVER = cppFile.o cFile.oBINS = $(BIN_SERVER)OBJS = $(OBJS_SERVER)all: $(BIN_SERVER) $(BIN_SERVER):$(OBJS_SERVER)$(CXX) -o $@ $^ $(LIBPATH) $(LIBS)install:@echo "nothing to install"clean:@-rm -f $(OBJS) $(BINS)@echo "clean over"
make
./myapp
在c++中可以成功調用c中定義的函數。
參考:
[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