如何对相互使用的C结构/函数声明进行排序?

如何对相互使用的C结构/函数声明进行排序?,c,function,pointers,struct,symbols,C,Function,Pointers,Struct,Symbols,我试图创建一个名为“IExampleVtbl”的结构,它将保存指向我的函数的指针(SetStringPtr,GetStringPtr),并且将是另一个结构的一部分 但是我想将另一个结构“IExample”作为参数传递给函数(SetStringPtr,GetStringPtr) 代码如下: #include <windows.h> #include <stdio.h> typedef struct { SetStringPtr *SetString; Ge

我试图创建一个名为“IExampleVtbl”的结构,它将保存指向我的函数的指针(SetStringPtr,GetStringPtr),并且将是另一个结构的一部分

但是我想将另一个结构“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);
}
#包括
#包括
类型定义结构{
SetStringPtr*SetString;
GetStringPtr*GetString;
}IExampleVtbl;
类型定义结构{
IExampleVtbl*lpVtbl;
德沃德计数;
字符缓冲区[80];
}例如;
typedef long SetStringPtr(例如*,char*);
typedef long GetStringPtr(例如*,char*,long);
长设置字符串(例如*this,char*str)
{
...
返回(0);
}
long GetString(例如*this,char*buffer,long-length)
{
...
返回(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
  • 函数指针的typedef
  • 结构定义
  • 函数定义
要使其正常工作,您需要使用标记定义结构:

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 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];
};

在所有作用域中,带有前导下划线和大写字母的符号保留给“实现”(编译器和标准库)。由于结构标记位于单独的名称空间中,它们可以与其他符号(如类型别名)具有相同的名称,因此不需要下划线。