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 。
, 。 , , , , , ; , , 。