c – 如何使用C头的声明来污染全局命名空间?

前端之家收集整理的这篇文章主要介绍了c – 如何使用C头的声明来污染全局命名空间?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在C中包装一个C库,使其成为一个现代的,高水平的,惯用的C库.我想要做的是使C对象完全不透明和/或直接从C代码中不可用,并用更高级别的替代品包装/替换它们.

我面临的问题很简单:我想只将C头包含在C源代码中,这样包含的C头也不会包含C头的声明,也就是说,它不会污染C头.全局命名空间

但看起来头文件和源文件的正确分离似乎不允许我这样做.这是我的问题的一个非常模糊的版本,评论将告诉你其余的:

my_header.h:

  1. typedef enum
  2. {
  3. my_Consts_ALPHA = /* some special value */,my_Consts_BETA = /* other special value */,} my_Consts;
  4.  
  5. typedef struct
  6. {
  7. // members...
  8. } my_Type;
  9.  
  10. void
  11. my_Type_method(my_Type *const,my_Enum);

my_header.hpp:

  1. namespace my
  2. {
  3. enum class Consts; // <-- This header is missing the constant values of
  4. // this enum,because its values are defined by
  5. // the C header :(
  6.  
  7. class Type : public my_Type // <-- The super struct is coming from the
  8. // C header,but I don't want to include
  9. // that header here :(
  10. {
  11. public:
  12. void
  13. method(Consts constant);
  14. };
  15. }

my_source.cpp:

  1. extern "C"
  2. {
  3. #include "my_header.h"
  4. }
  5.  
  6. #include "my_header.hpp"
  7.  
  8. namespace my
  9. {
  10. enum class Consts
  11. {
  12. ALPHA = my_Consts_ALPHA,BETA = my_Consts_BETA,};
  13.  
  14. void
  15. Type::method(Consts constant)
  16. {
  17. my_Type_method(static_cast<my_Type *const>(this),static_cast<my_Consts>(constant));
  18. }
  19. }

所以我的问题是:我错过了一些非常明显的东西吗?这有可能实现吗?有没有我不知道的伎俩?

解决方法

在讽刺性地提出的问题 @AnalPhabet评论中,应该在命名空间内使用#include的C头. @n.m.证实,它实际上是一个有效的解决方案,现在我在自己的设置上进行了测试,幸运的是它工作得很好.

(虽然我不知道,如果这是特定于实现或不是,但我测试了g和clang并且它正在工作.)

它没有解决不透明性问题,但至少它直接访问原始C数据有点困难,因为它现在生活在一个单独的命名空间中,因此用户不能偶然访问,而是心甘情愿.

所以,my_header.hpp应如下所示:

  1. namespace my
  2. {
  3. extern "C"
  4. {
  5. #include "my_header.h"
  6. }
  7.  
  8. enum class Consts
  9. {
  10. ALPHA = my_Consts_ALPHA,};
  11.  
  12. class Type : public my_Type
  13. {
  14. public:
  15. void
  16. method(Consts constant);
  17. };
  18. }

因此,无论my_header.hpp在哪里#include,用户只能访问C值,如下所示:

  1. my::my_Consts_ALPHA // The wrapped value is => my::Consts::ALPHA
  2. my::my_Type // The wrapped value is => my::Type
  3. my::my_Type_method(t,..) // The wrapped value is => t.method(..)

猜你在找的C&C++相关文章