2012-09-22 80 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