4

I am trying to create a structure by the name "IExampleVtbl" that will hold a pointer to my functions (SetStringPtr,GetStringPtr) and will be a part of another structure "IExample".

But I want to pass the other structure "IExample" as parameter to the functions (SetStringPtr,GetStringPtr).

This is the code:

#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);
}

As you can see the first structure need to know about the functions, the functions need to know about the second structure which need to know about the first structure.

How I can solved that?

Richard Chambers
  • 16,643
  • 4
  • 81
  • 106
NinjaYo.
  • 103
  • 6

3 Answers3

4

You can solve the problems by putting things in the following order

  • typedefs for the structures
  • typedefs for the function pointers
  • structure definitions
  • function definitions

To make that work, you'll need to define the structures with tags:

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);
}
user3386109
  • 34,287
  • 7
  • 49
  • 68
1

You combine a forward declaration with the type-alias definition:

// 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 { ... };
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

typedef for the struct to be typedef'd can precede the definition of struct, so a bit of re-arrangement should make things work here

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];
};
Aniruddh Dikhit
  • 662
  • 4
  • 10
  • Symbols with leading underscore followed by an upper-case letter is reserved for the "implementation" (compiler and standard library) in all scopes. And since structure tags live in a separate namespace, they can have the same name as other symbols (like the type-alias) so the underscore isn't needed. – Some programmer dude Feb 25 '17 at 18:46
  • [What are the rules about using an underscore in a C++ identifier?](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) – Richard Chambers Feb 25 '17 at 18:50