简体   繁体   English

了解将结构转换为空指针

[英]Understanding casting a struct as a void pointer

I found this code in the rendering library for Quake 3. There is this function: 我在Quake 3的渲染库中找到了此代码。有以下功能:

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

It is being called in a loop somehwere else like this: 正在循环中调用它,如下所示:

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

The weird part is that poly was declared as srfPoly_t *poly . 奇怪的是,poly被声明为srfPoly_t *poly What is going on here? 这里发生了什么? It is casting a srfPoly_t object to (void *) and then entering the function as a surfaceType_t object. 它是铸造一个srfPoly_t对象(void *)然后在进入用作surfaceType_t对象。

Here are the declaration for the relevant structs: 以下是相关结构的声明:

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;

This is working in C, but I am trying to implement something similar in C++, but I get the following error: 这在C语言中有效,但是我试图在C ++中实现类似的功能,但是出现以下错误:

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

It would appear I cannot perform this type of cast in C++, or maybe there is something else I am unable to understand. 看来我无法在C ++中执行这种类型的转换,或者也许还有其他我无法理解的东西。 I am not very familiar with C++ and would love to figure out how to set up something similar using it. 我对C ++不太熟悉,很想弄清楚如何使用C ++建立类似的东西。

I am assuming this has something to do with type checking in C++, so it is not allowed. 我假设这与C ++中的类型检查有关,因此是不允许的。 How can I implement something similar in C++ in a safe way? 如何以安全的方式在C ++中实现类似的功能?

This works in C because structs are simply blocks of memory with each element in the struct laid out consecutively. 这在C语言中有效,因为结构只是内存块,结构中的每个元素都连续排列。 This cast works because the first n bytes of a srfPoly_t struct consist of the surfaceType_t enum within that struct. 该投工作,因为第一n一个字节srfPoly_t结构组成的的surfaceType_t该结构中枚举。 The called function tries to interpret the passed-in srfPoly_t as a surfaceType_t , and succeeds because the first n bytes of the argument are, in fact, a surfaceType_t . 被调用的函数试图解释传入的srfPoly_t作为surfaceType_t ,并成功,因为第一n的说法字节,事实上,一个surfaceType_t Do not do this without a very good reason. 没有充分的理由就不要这样做。

Casts from void* 's do not automatically occur in C++ as they do in C. You can use reinterpret_cast to explicitly cast between two different types of structs: void*的强制转换不会像在C中那样自动在C ++中进行。您可以使用reinterpret_cast在两种不同类型的结构之间显式进行强制转换:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM