如何在C代码中模拟C++命名空间功能?

Mom*_*gil 8 c c++ namespaces

我正在开发一个C++软件,但它通过包含通信协议的共享头文件与C app进行通信.由于C比C++"更基本",我总是需要在C代码中编写头文件(所以C++也可以得到它); 否则它不适用于第二个应用程序.

问题是我需要使用范围调整器,例如C++ namespace,它在C中不存在.

在C中模拟该功能的所有选项有哪些namespace

到目前为止我唯一可能看到的是这个SO问题,但遗憾的是答案不够明确,我当然想知道是否有其他选择.我也尝试使用structs来完成这项工作,但没有成功(至少考虑struct使用enumerator).

Leu*_*nko 10

您可以隐藏static在定义级别从模块导出的所有导出函数,这样就不会在全局空间中放置任何名称,而是将它们放在模块提供的唯一结构中.

例如foo.h:

struct ns_t {
    int (*a)(int, int);
    void (*b)(float, float);
};
extern struct ns_t ns;
Run Code Online (Sandbox Code Playgroud)

foo.c的:

#include "foo.h"

static int a(int x, int y) {
    ...
}

static void b(float x, float y) {
    ...
}

struct ns_t ns = { .a = a, .b = b };
Run Code Online (Sandbox Code Playgroud)

bar.c:

#include "foo.h"
....
ns.b(4.5, 6.8);
....
Run Code Online (Sandbox Code Playgroud)

  • 这是一个有趣的名称空间.虽然可能会对性能造成不良影响,但由于总是跳过这些全局指针...... (4认同)

Ded*_*tor 6

不要在C中模拟名称空间,转到C方式:

  • 使用前缀而不是名称空间.
  • 使用后缀而不是重载.
    • (可选)使用宏_Generic来模拟参数类型的重载.

您的包含文件应该在C++的内部详细命名空间中定义那些C函数(由于C链接,不会更改函数实际标识),然后从C函数的C函数中删除前缀和后缀.
它看起来像这样:

#ifndef MY_HEADER_GUARD_unique_suffix
#define MY_HEADER_GUARD_unique_suffix
#ifdef __cplusplus
namespace my_module {
namespace detail {
extern "C" {
#endif
// Defines for common structs and functions here
// Also inline functions written in the common intersection of C and C++
#ifdef __cplusplus
}
}
using init = detail::my_module_init;
using close = detail::my_module_close;
}
#endif
#endif
Run Code Online (Sandbox Code Playgroud)

您可能还希望将成员函数添加到C++接口的某些C结构中,这可能是委托给共享函数的内联函数.

  • @Momergil:它们用于剥离任何前缀(C替代命名空间)和后缀(C替代重载).顺便说一句:您可以使用`_Generic`在C中提供没有后缀的接口. (3认同)