如何订购相互使用的 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];
};
我正在尝试创建一个名为 "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];
};