如何订购相互使用的 C structure/function 声明?

How to order C structure/function declarations which use each other?

我正在尝试创建一个名为 "IExampleVtbl" 的结构,它将保存指向我的函数的指针 (SetStringPtr,GetStringPtr) 并且将成为另一个结构 "IExample" 的一部分。

但我想将另一个结构 "IExample" 作为参数传递给函数 (SetStringPtr,GetStringPtr).

这是代码:

#include <windows.h>
#include <stdio.h>

typedef struct {
    SetStringPtr *SetString;
    GetStringPtr *GetString;
} IExampleVtbl;

typedef struct {
    IExampleVtbl *lpVtbl;
    DWORD   count;
    char    buffer[80];
} IExample;

typedef long SetStringPtr(IExample *, char *);
typedef long GetStringPtr(IExample *, char *, long);

long SetString(IExample *this, char * str)
{
    ...

    return(0);
}

long GetString(IExample *this, char *buffer, long length)
{
    ...

    return(0);
}

如您所见,第一个结构需要了解函数, 函数需要知道第二个结构,而第二个结构需要知道第一个结构。

我该如何解决?

您将 前向声明 与类型别名定义相结合:

// Forward declaration of the structure IExample
// And at the same time definition of the type-alias IExample
typedef struct IExample IExample;

typedef long SetStringPtr(IExample *, char *);
typedef long GetStringPtr(IExample *, char *, long);

// Now the definition of the structures
typedef struct { ... } IExampleVtbl;

// Because the previous type-alias definition, we need to specify a structure tag
struct IExample { ... };

你可以按照以下顺序来解决问题

  • 结构的类型定义
  • 函数指针的类型定义
  • 结构定义
  • 函数定义

要实现这一点,您需要使用标签定义结构:

typedef struct IExampleVtblTag IExampleVtbl;
typedef struct IExampleTag IExample;
typedef long SetStringPtr(IExample *, char *);
typedef long GetStringPtr(IExample *, char *, long);

struct IExampleVtblTag {
    SetStringPtr *SetString;
    GetStringPtr *GetString;
};

struct IExampleTag {
    IExampleVtbl *lpVtbl;
    DWORD   count;
    char    buffer[80];
};

long SetString(IExample *this, char * str)
{
    return(0);
}

long GetString(IExample *this, char *buffer, long length)
{
    return(0);
}

要进行 typedef 的结构的 typedef 可以先于结构的定义,因此稍微重新安排一下应该可以使这里正常工作

typedef struct IExample IExample;

typedef long SetStringPtr(IExample *, char *);
typedef long GetStringPtr(IExample *, char *, long);

typedef struct {
    SetStringPtr *SetString;
    GetStringPtr *GetString;
} IExampleVtbl;

struct IExample {
    IExampleVtbl *lpVtbl;
    long   count;
    char    buffer[80];
};