1

下面的代码解释了我遇到的情况:

#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 链接函数放在 namespacens中,否则 C 客户端将找不到它们的定义。当我将它们拉出命名空间时,C++ 定义也不会编译,这都是因为pod我从C++ FAQ Lite中学到的解决方案,它只是一个预处理器技巧。可悲的是,这个技巧无法处理命名空间。

我应该做些什么?我应该抛弃所有类型安全,并用 替换pod*void*还是有更好的解决方案来解决这种情况?有什么建议吗?请!

4

2 回答 2

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 podorstruct ns_pod是一个不完整的类型,所以在 C 中你永远不能直接做任何使用字段或询问其大小的事情。指向不完整类型的指针和 a 之间的区别在于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 程序员不赞成强制转换的原因之一。

于 2012-09-22T12:08:18.077 回答
1

我自己弄清楚了:) 通过检查 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
于 2012-09-22T12:59:41.980 回答