无法转发声明C typedef结构-正在查找其他建议

Cannot forward declare a C typedef struct - looking for alternative suggestions

本文关键字:查找 其他 结构 转发 声明 typedef      更新时间:2023-10-16

我使用的是第三方C库(Raylib(,该库在标头中定义了宏和struct,如下所示:

// raylib.h
#define RED { 230, 41, 55, 255 }     // Red
// Color type, RGBA (32bit)
typedef struct Color {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
} Color;

我想把它封装在我自己的C++头和名为engine.hengine.cc的源文件中,它们只公开相关的函数和宏。

为了确保只有engine.cc可以访问标头raylib.h,我理想情况下希望:

  1. engine.h中转发声明struct Color
  2. #include "raylib.h"仅在engine.cc

类似的东西(来源(:

// engine.h
// Forward declare.
struct Color;
typedef struct Color Color;
namespace Engine {
namespace Colors {
const extern Color Red;
}
void SetBackgroundColor(Color color);
};
// engine.cc
#include "engine.h"
#include "raylib.h"
namespace Engine {
namespace Colors {
const Color Red = RED;
}
void SetBackgroundColor(Color color) {
::SetBackgroundColor(color);
}
}

不幸的是,这不起作用,因为我不能转发声明typedef,因为它也在typedef中定义了结构。

我的问题是,如果我想对包括engine.h的所有其他文件隐藏raylib.h,最好的选择是什么?

我尝试过的一种方法是拥有自己的enum class颜色,然后由engine.cc中匿名命名空间中的辅助函数解析。helper函数使用switch语句来解析它。但这很乏味,因为我需要为我想使用的每一种新颜色写很多代码。此外,Color只是具有相关宏的结构之一。还有很多,我不想为它们中的每一个创建这些辅助函数。

我解决了这个问题,但在一个与raylib.h中的名称空间相同的名称空间中定义了我自己的struct Color,并在engine.cc中创建了一个将一个转换为另一个的辅助函数。

// engine.h
namespace Engine {
namespace Colors {
struct Color {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
};
extern const Color Red;
extern const Color Green;
extern const Color Blue;
extern const Color Black;
}  // namespace Colors
void SetBackgroundColor(const Colors::Color);
}  // namespace Engine


// engine.cc
namespace Engine {
using RayColor = ::Color;
namespace Colors {
const Color Red = RED;
const Color Green = GREEN;
const Color Blue = BLUE;
const Color Black = BLACK;
namespace {
RayColor GetRayColor(const Color color) {
return RayColor{color.r, color.g, color.b, color.a};
}
}  // namespace
}  // namespace Colors
void SetBackgroundColor(const Colors::Color color) {
::ClearBackground(Colors::GetRayColor(color));
}
}  // namespace Engine

这是因为我可以很容易地从Engine::Colors::Color转换为Color。此外,因为所有的颜色宏都只是大括号中的数字,所以我可以很容易地使用它们来分配给我自己的结构。

当然,这个解决方案是针对raylib.h和我的需求的。我希望这个问题能有一个更普遍的解决办法。

我不确定这种方法会对性能造成多大影响,但我现在会尝试一下,如果它破坏了任何东西,我会再次访问。