• C

Compiler errors

Can anyone help me compile the following code?  I keep getting errors concerning the typedef definitions.  
They reference one another in such a way that it keeps throwing errors.  Can anyone correct this?  I have
been using MS Visual Studio .NET to compile the code.

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

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

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

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

long SetString(IExample *this, char * str);
long GetString(IExample *this, char *buffer, long length);

void
main (int argc, char *argv[])
{
      // Since the contents of IExample_Vtbl will never change, we'll
      // just declare it static and initialize it that way. It can
      // be reused for lots of instances of IExample.
      static IExampleVtbl IExample_Vtbl = {SetString, GetString};

      IExample * example;

      // Create (allocate) a IExample struct.
      example = (IExample *)GlobalAlloc(GMEM_FIXED, sizeof(IExample));

      // Initialize the IExample (ie, store a pointer to
      // IExample_Vtbl in it).
      example->lpVtbl = &IExample_Vtbl;
      example->count = 1;
      example->buffer[0] = 0;

      char buffer[80];

      example->lpVtbl->SetString(example, "Some text");
      example->lpVtbl->GetString(example, buffer, sizeof(buffer));

      exit (0);

} // main

long SetString(IExample *this, char * str)
{
   DWORD  i;

   // Let's copy the passed str to IExample's buffer
   i = lstrlen(str);
   if (i > 79) i = 79;
   CopyMemory(this->buffer, str, i);
   this->buffer[i] = 0;

   return(0);
}

long GetString(IExample *this, char *buffer, long length)
{
   DWORD  i;

   // Let's copy IExample's buffer to the passed buffer
   i = lstrlen(this->buffer);
   --length;
   if (i > length) i = length;
   CopyMemory(buffer, this->buffer, i);
   buffer[i] = 0;

   return(0);
}
jtradesAsked:
Who is Participating?
 
rajeev_devinConnect With a Mentor Commented:
Corrected code

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

struct IExample_;

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

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

struct IExample_{
   IExampleVtbl_ * lpVtbl;
   DWORD          count;
   char           buffer[80];
};

typedef struct IExample_ IExample;
typedef struct IExampleVtbl_ IExampleVtbl;

long SetString(IExample *obj, char * str);
long GetString(IExample *obj, char *buffer, long length);


void
main (int argc, char *argv[])
{
     // Since the contents of IExample_Vtbl will never change, we'll
     // just declare it static and initialize it that way. It can
     // be reused for lots of instances of IExample.
     static IExampleVtbl IExample_Vtbl = {SetString, GetString};

     IExample * example;

     // Create (allocate) a IExample struct.
     example = (IExample *)GlobalAlloc(GMEM_FIXED, sizeof(IExample));

     // Initialize the IExample (ie, store a pointer to
     // IExample_Vtbl in it).
     example->lpVtbl = &IExample_Vtbl;
     example->count = 1;
     example->buffer[0] = 0;

     char buffer[80];

     example->lpVtbl->SetString(example, "Some text");
     example->lpVtbl->GetString(example, buffer, sizeof(buffer));

     exit (0);

} // main

long SetString(IExample *obj, char * str)
{
   DWORD  i;

   // Let's copy the passed str to IExample's buffer
   i = strlen(str);
   if (i > 79) i = 79;
   CopyMemory(obj->buffer, str, i);
   obj->buffer[i] = 0;

   return(0);
}

long GetString(IExample *obj, char *buffer, long length)
{
   DWORD  i;

   // Let's copy IExample's buffer to the passed buffer
   i = strlen(obj->buffer);
   --length;
   if (i > length) i = length;
   CopyMemory(buffer, obj->buffer, i);
   buffer[i] = 0;

   return(0);
}
0
 
rajeev_devinCommented:
What is IExample ?
Where it is defined ?
0
 
rajeev_devinCommented:
Sorry I didn't read the code properly
0
Improved Protection from Phishing Attacks

WatchGuard DNSWatch reduces malware infections by detecting and blocking malicious DNS requests, improving your ability to protect employees from phishing attacks. Learn more about our newest service included in Total Security Suite today!

 
rajeev_devinCommented:
>> i = lstrlen(str);
Don't use lstrlen(...) for char*.
Because for unicode project it will expect the parameter to be wchar_t*.
At that time you may get compilation error.
0
 
cryptosidCommented:
typedef long SetStringPtr(IExample *, char *);
typedef long GetStringPtr(IExample *, char *, long);

doesn't seem to be correct, pls comment and try recompiling.

feel a bit rusty since i haven't compiled for a long time :-)

Regards,
siddhesh
0
 
rajeev_devinCommented:
Don't use keywords like 'this' in a program.
I know 'this' is not applicable for C.
But if you compile it in C++ compiler then you may get errors.

So, its better to be safe :-)
0
 
cupCommented:
The problem is forward referencing.  Try this

struct IExampleStr;  // Add this
typedef long SetStringPtr(struct IExampleStr *, char *);  // Change this defn
typedef long GetStringPtr(struct IExampleStr *, char *, long);  // Change this defn

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

typedef struct IExampleStr {  // Add the structure name here
   IExampleVtbl * lpVtbl;
   DWORD          count;
   char           buffer[80];
} IExample;

I've noticed that you're using this as a parameter.  While it is legal in C, it isn't in C++.  Might be better to rename it to that so that if in the future this program gets compiled as C++, you won't get any problems.
0
 
cupCommented:
Oops sorry rajeev - I didn't refresh my screen.  You've already given the solution.
0
 
cupCommented:
Cryptosid,  that is the standard way of typedefing a function.  Basically it is

typedef <return type> <typedef name> (<function parameters>);

Some compilers insist that you have appropriate *s so it could be something complex like

typedef long (*SetStringPtr)(struct IExampleStr*, char*);
0
 
cryptosidCommented:
Ah!

You see I have forgotten that typedef could also be used for functions.

Regards,
Siddhesh
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.