2012-09-22 121 views
0

下面的代碼說明的情況我遇到:命名空間和C++/C混合頭

#ifdef __cplusplus 
namespace ns 
{ 
class pod 
{ 
    const short foo; 
    const char bar; 
public: 
    pod(short f,char b):foo(f),bar(b){} 
    char foobar(); 
}; 
} 
#else 
typedef struct pod pod; 
#endif 


#ifdef __cplusplus 
extern "C"{ 
#endif 

extern pod* pod_new(short f, char b);//BANG!!! 
extern char pod_foobar(pod* p); //BANG!!! 

#ifdef __cplusplus 
} 
#endif 

我不能把C鏈接功能的命名空間ns內,或C客戶機將無法找到它們的定義。當我將它們從命名空間中取出時,C++定義將不會編譯,全都是因爲我從C++ FAQ Lite得知的pod解決方案,它只是一個預處理器技巧。可悲的是,這個技巧無法處理命名空間。

我該怎麼辦?我是否應該拋棄所有類型安全性,並用void*替換pod*,或者在這種情況下是否有更好的解決方案?任何建議?請!

+0

我想這是一個煮制的例子,但你的'typedef'錯過了一個';' –

回答

3

我只是給出了兩個不同的聲明功能

爲C++:

extern "C" ns::pod* pod_new(short f, char b); 
extern "C" char pod_foobar(ns::pod* p); 

和C:

typedef struct pod pod; 
extern pod* pod_new(short f, char b); 
extern char pod_foobar(pod* p); 

但如果這不能滿足你,因爲C++你也可以有一個typedef

typedef ns::pod ns_pod; 

對於C

typedef struct ns_pod ns_pod; 

,然後具有相同的通用功能的原型。

extern ns_pod* pod_new(short f, char b); 
extern char pod_foobar(ns_pod* p); 

編輯:在C struct podstruct ns_pod是一個不完整的類型,所以用C直接,你永遠無法做任何事情,使用字段或詢問其大小。指向不完整類型的指針與void*之間的區別在於,您只能將這樣的struct指針指派給另一個具有相同不完整類型的struct指針。

typedef struct ns_pod2 pod2; 
ns_pod* q = pod_new(...); // valid 
ns_pod2* r = pod_new(...); // a constraint violation! (= compiler error) 

如果你想堅持,第二個需要明確的轉換。這是許多C程序員爲什麼不理解演員陣容的原因之一。

+0

它不是一個定義規則嗎? (你爲C++定義'ns :: pod','C'定義':: pod') – Lol4t0

+0

@ jens-gustedt謝謝你的迴應。我不希望我的C++端代碼被這個混合頭部所污染。那麼你或者任何人都可以向我解釋ns:pod *和C端typedefed pod *之間的關係嗎?我知道在C + +端ns :: pod保持類型檢查,但在C端,不完整的結構名稱真的意味着什麼? – Need4Steed

+0

@ Lol4t0,沒有隻有一個定義,C從來沒有看到任何定義。在C中只有一個前向聲明,'struct pod'或'struct ns_pod'是一個不完整的類型。 –

0

我想通過檢查obj文件的符號nm自己:)。

事實證明,C++的命名空間對C鏈接功能沒有影響,因此我可以重寫上面的代碼是這樣的:

#ifdef __cplusplus 
namespace ns 
{ 
class pod 
{ 
    const short foo; 
    const char bar; 
public: 
    pod(short f,char b):foo(f),bar(b){} 
    char foobar(); 
}; 
} 


#else 
typedef struct pod pod; 
#endif 


#ifdef __cplusplus 
namespace ns{ 
extern "C"{ 
#endif 

pod* pod_new(short f, char b); 
char pod_foobar(pod* p); 
void pod_free(pod* p); 

#ifdef __cplusplus 
} 
} 
#endif