命名空间和 C++/C 混合标头

namespace and c++/c mixed header

本文关键字:混合 C++ 命名空间      更新时间:2023-10-16

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

#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++定义也不会编译,这都是因为我从 FAQ Lite C++学到的pod解决方案,这只是一个预处理器技巧。可悲的是,这个技巧无法处理命名空间。

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

我只为函数提供两种不同的声明

对于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程序员不赞成强制转换的原因之一。

我自己想通了:)通过使用 nm 检查 OBJ 文件的符号。

事实证明,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