c++ - 了解将结构转换为 void 指针

标签 c++ c

我在Quake 3的渲染库中找到这段代码,有这个功能:

void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader, int fogIndex, int dlightMap );`

它在循环中被调用,就像这样:

R_AddDrawSurf( ( void * )poly, sh, poly->fogIndex, qfalse );

奇怪的是 poly 被声明为 srfPoly_t *poly。到底是怎么回事 这里?它正在将 srfPoly_t 对象转换为 (void *) 然后输入 用作 surfaceType_t 对象。

以下是相关结构的声明:

typedef enum {
  SF_BAD,
  SF_SKIP,        // ignore
  SF_FACE,
  SF_GRID,
  SF_TRIANGLES,
  SF_POLY,
  SF_MD3,
  SF_MD4,
  SF_FLARE,
  SF_ENTITY,        // beams, rails, lightning, etc that can be determined by entity
  SF_DISPLAY_LIST,

  SF_NUM_SURFACE_TYPES,
  SF_MAX = 0x7fffffff     // ensures that sizeof( surfaceType_t ) == sizeof( int )
} surfaceType_t;

typedef struct srfPoly_s {
  surfaceType_t surfaceType;
  qhandle_t   hShader;
  int       fogIndex;
  int       numVerts;
  polyVert_t    *verts;
} srfPoly_t;

这在 C 中有效,但我试图在 C++ 中实现类似的东西, 但我收到以下错误:

Error   1   error C2664: 'int RefDef::AddDrawSurf(surfaceType_t *)' : cannot convert argument 1 from 'void *' to 'surfaceType_t *'

看来我无法在 C++ 中执行这种类型的强制转换,或者也许有 我无法理解的其他事情。我不是很熟悉 C++ 和 很想弄清楚如何使用它来设置类似的东西。

我假设这与 C++ 中的类型检查有关,所以它不是 允许。如何以安全的方式在 C++ 中实现类似的东西?

最佳答案

这在 C 中有效,因为结构只是内存块,结构中的每个元素都是连续排列的。此转换有效,因为 srfPoly_t 结构的前 n 字节由该结构内的 surfaceType_t 枚举组成。被调用函数尝试将传入的 srfPoly_t 解释为 surfaceType_t,并成功,因为参数的前 n 个字节实际上是,一个 surfaceType_t。没有充分的理由不要这样做。

来自 void* 的转换不会像在 C 中那样自动发生在 C++ 中。您可以使用 reinterpret_cast 在两种不同类型的结构之间显式转换:

srfPoly_t* mySrfPoly_t;
surfaceType_t* mySurfaceType = reinterpret_cast<surfaceType_t*>(mySrfPoly_t);

关于c++ - 了解将结构转换为 void 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25496289/

相关文章:

c++ - 从整数 vector 列表中删除重复项的快速方法

c++ - ghc 7.6.3 不生成 _stub.c 和 _stub.o

c++ - 找不到内存泄漏

c - 从头开始实现malloc函数的问题

c - 输入值创建二叉搜索树

c - 鉴于recvfrom和sendto的阻塞性质,如何实现超时?

c - 我得到了意外的输出

c++ - C++ 模板变体中的类型数量是否有限制?

c++ - 如何从客户端代码中隐藏模板化的非成员函数?

c - 在 C 中声明 Pascal 风格的字符串