extern「C」ネストについて

12249 ワード

  : http://effective-c.googlecode.com/svn-history/r67/wiki/EffectiveC.wiki

== 1: #include extern "C" == , : {{{ #ifndef __MY_HANDLE_H__ #define __MY_HANDLE_H__ }}} {{{ #ifdef __cplusplus extern "C" { #endif }}} {{{ #include <typedef.h> #include <errcode.h> }}} {{{ typedef void* my_handle_t; my_handle_t create_handle(const char* name); result operate_on_handle(my_handle_t handle); void close_handle(my_handle_t handle); }}} {{{ #ifdef __cplusplus } #endif }}} {{{ #endif /* __MY_HANDLE_H__ */ }}} , :“ , , ~” , C++ 。 C++ ? `__cplusplus` C++ 。`__cplusplus` C++ , : C++ ; C 。 , `__cpluplus` *199711L* —— , g++ 1, 。 , C , : {{{ #ifndef __MY_HANDLE_H__ #define __MY_HANDLE_H__ #include <typedef.h> #include <errcode.h> typedef void* my_handle_t; my_handle_t create_handle(const char* name); result operate_on_handle(my_handle_t handle); void close_handle(my_handle_t handle); #endif /* __MY_HANDLE_H__ */ }}} , *extern "C" { ... }* , *#include* 。 C++ , : {{{ #ifndef __MY_HANDLE_H__ #define __MY_HANDLE_H__ }}} {{{ extern "C" { }}} {{{ #include <typedef.h> #include <errcode.h> typedef void* my_handle_t; my_handle_t create_handle(const char* name); result operate_on_handle(my_handle_t handle); void close_handle(my_handle_t handle); }}} {{{ } }}} {{{ #endif /* __MY_HANDLE_H__ */ }}} , , *#include* , *extern "C" { ... }* 。 *extern "C"* ? ? 。 ===extern "C" === C++ , , *“ ”(name mangling)* 。 C++ , , , 。 C++ , C++ , 。 , , , * (function overloading)* ; , , * (namespace)* 。 , , , , , 。 ,C++ C : , ; , 。 , , 。 ; 。 , * * , , , , 。 C , , , ,C 。 , , , static ; , , , 。 ,C ( , `_`)。 C++ Bjarne Stroustrup —— C, C —— C++ 。 , 。 , my_handle.h , : {{{ #ifndef __MY_HANDLE_H__ #define __MY_HANDLE_H__ typedef unsigned int result; typedef void* my_handle_t; my_handle_t create_handle(const char* name); result operate_on_handle(my_handle_t handle); void close_handle(my_handle_t handle); #endif /* __MY_HANDLE_H__ */ }}} my_handle.h my_handle.c C , : {{{ #include "my_handle.h" my_handle_t create_handle(const char* name) { ... return (my_handle_t)handle; } result operate_on_handle(my_handle_t handle) { ... return SUCCESS; } void close_handle(my_handle_t handle) { ... } }}} C my_handle.c, my_handle.o。 C , my_handle.o , 。 : {{{ 0000001a T _close_handle 00000000 T _create_handle 0000000d T _operate_on_handle }}} , C++ , , my_handle.h。 C++ my_handle_client.cpp, : {{{ #include "my_handle.h" void my_handle_client::do_something(const char* name) { my_handle_t handle = create_handle(name); (void) operate_on_handle(handle); close_handle(handle); } }}} C++ , my_handle_client.o。 C++ , : {{{ 0000002c s EH_frame1 U __Z12close_handlePv U __Z13create_handlePKc U __Z17operate_on_handlePv 00000000 T __ZN16my_handle_client12do_somethingEPKc 00000048 S __ZN16my_handle_client12do_somethingEPKc.eh }}} , my_handle.h : {{{ __Z12close_handlePv __Z13create_handlePKc __Z17operate_on_handlePv }}} , , my_handle.o my_handle_client.o 。 , “ ” 。 {{{ Undefined symbols: "close_handle(void*)", referenced from: my_handle_client::do_something(char const*)in my_handle_client.o "create_handle(char const*)", referenced from: my_handle_client::do_something(char const*)in my_handle_client.o "operate_on_handle(void*)", referenced from: my_handle_client::do_something(char const*)in my_handle_client.o }}} ,C++ * (linkage specifacition)* , *extern "language string"* ,C++ *"language string"* "C" "C++", C C++ 。 * * C++ : * * , * * , 。 * * : 1. , : {{{ extern "C" void foo(); }}} 2. , : {{{ extern "C" { void foo(); int bar(); } }}} , my_handle.h : {{{ #ifndef __MY_HANDLE_H__ #define __MY_HANDLE_H__ extern "C" { typedef void* my_handle_t; my_handle_t create_handle(const char* name); result operate_on_handle(my_handle_t handle); void close_handle(my_handle_t handle); } #endif /* __MY_HANDLE_H__ */ }}} C++ my_handle_client.cpp, my_handle_client.o : {{{ 0000002c s EH_frame1 00000000 T __ZN16my_handle_client12do_somethingEPKc 00000048 S __ZN16my_handle_client12do_somethingEPKc.eh U _close_handle U _create_handle U _operate_on_handle }}} , , *extern "C"* , C 。 , my_handle.o my_handle_client.o , “ ” 。 , my_handle.c,C “ ”, extern "C" C++ ,C 。 , , `__cplusplus` C C++ 。 my_handle.h : {{{ #ifndef __MY_HANDLE_H__ #define __MY_HANDLE_H__ #ifdef __cplusplus extern "C" { #endif typedef void* my_handle_t; my_handle_t create_handle(const char* name); result operate_on_handle(my_handle_t handle); void close_handle(my_handle_t handle); #ifdef __cplusplus } #endif #endif /* __MY_HANDLE_H__ */ }}} === === *extern "C"* , , *#include* *extern "C" { ... }* ? , a.h,b.h,c.h foo.cpp, foo.cpp c.h,c.h b.h,b.h a.h, : a.h : {{{ #ifndef __A_H__ #define __A_H__ #ifdef __cplusplus extern "C" { #endif void a(); #ifdef __cplusplus } #endif #endif /* __A_H__ */ }}} b.h : {{{ #ifndef __B_H__ #define __B_H__ #ifdef __cplusplus extern "C" { #endif #include "a.h" void b(); #ifdef __cplusplus } #endif #endif /* __B_H__ */ }}} c.h : {{{ #ifndef __C_H__ #define __C_H__ #ifdef __cplusplus extern "C" { #endif #include "b.h" void c(); #ifdef __cplusplus } #endif #endif /* __C_H__ */ }}} foo.cpp : {{{ #include "c.h" }}} C++ foo.cpp, : {{{ extern "C" { extern "C" { extern "C" { void a(); } void b(); } void c(); } }}} , *#include* *extern "C" { ... }* , *extern "C" { ... }* 。 C++ 。 , 。 , foo C++ , bar C 。 {{{ extern "C" { extern "C++" { void foo(); } void bar(); } }}} C C , C++ , 。 , MSVC2005, *extern "C" { } * 。 , , 。 *#include* *extern "C" { }* 。 , *#include* *extern "C" { }* , C++ foo.cpp, : {{{ extern "C" { void a(); } extern "C" { void b(); } extern "C" { void c(); } }}} —— MSVC。 *#include* *extern "C" { }"* , 。 : a.h : {{{ #ifndef __A_H__ #define __A_H__ #ifdef __cplusplus void foo(int); #define a(value) foo(value) #else void a(int); #endif #endif /* __A_H__ */ }}} b.h : {{{ #ifndef __B_H__ #define __B_H__ #ifdef __cplusplus extern "C" { #endif #include "a.h" void b(); #ifdef __cplusplus } #endif #endif /* __B_H__ */ }}} , C++ b.h, : {{{ extern "C" { void foo(int); void b(); } }}} a.h , foo C++ , * * "C++"。 b.h , *#include "a.h"* *extern "C" { }* , foo * * "C"。 *#include* , , , *#include* *extern "C" { }* , , 。 ,“ , ”。 , ? , ? ===Q&A=== ====Q: / C —— a.h—— extern "C" ?==== A: a.h 。 , a.h extern "C", b.cpp a.h, b.cpp {{{ extern "C" { #include "a.h" } }}} , 。 , , a.h。 : # , ; # , , 。 , workaround, 。 , bug, 。 , 。 , 。 , , patch 。 , 。 , , , , , ; , , 。