簡體   English   中英

無法轉發聲明 C typedef 結構 - 尋找替代建議

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

我正在使用第三方 C 庫 ( Raylib ),它在 header 中定義了如下宏和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++ header 和名為engine.hengine.cc的源文件中,它們只公開相關的函數和宏。

為了確保只有engine.cc可以訪問 header 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 中定義了結構。

我的問題是,如果我想讓raylib.h對包括engine.h的所有其他文件隱藏起來,最好的選擇是什么?

我嘗試過並且有效的一種方法是擁有自己的enum class的 colors 然后由助手engine.cc解決,該助手位於引擎中的匿名命名空間中。 助手 function 使用switch語句解決它。 但這很乏味,因為我需要為我想使用的每種新顏色編寫大量代碼。 此外, Color只是具有關聯宏的結構之一。 還有更多,我不想為它們中的每一個都創建這些輔助函數。

我解決了這個問題,但是在與raylib.h相同的命名空間中定義了我自己的struct Color並創建了一個幫助器 function ,它將一個轉換為另一個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和我的要求。 我希望有一個更通用的解決方案來解決這個問題。

我不確定這種方法對性能的影響有多大,但我現在會嘗試一下,如果它破壞了任何東西,我會重新訪問。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM