Private static function pointer problem :)

Started by
10 comments, last by Error98 18 years, 7 months ago
Hi! I have a problem with private static function pointer :) (it looks something like this)

class Engine2D
{
private:
static unsigned long          (*ConvertToGraphicMode)(long red, long green, long blue);
}

When i want to compile code error pops: "error LNK2001: unresolved external symbol "private: static unsigned long (__cdecl* Engine2D::ConvertToGraphicMode)(long,long,long)" (?ConvertToGraphicMode@Engine2D@@0P6AKJJJ@ZA) Debug/3D Engine.exe : fatal error LNK1120: 1 unresolved externals" well .. i know that static members must be initialized somehow but i can't do it like this Engine::ConvertToGraphicMode = NULL; becouse another error pops that i am not allowed to use private members in this way. Anybody know how to fix this?
Advertisement
When you add a static member to a class, all you are doing is declaring that member (tell the compiler the variable exists, somewhere). You still need to define it, separately, in a single translation unit (i.e. in a .cpp file), to actually bring it into existence in your program. Declarations placate the compiler, but when the linker comes in to piece your program together, it'll go "Hey, you're using that variable, but it doesn't exist anywhere in the program".

Typically, this means doing:

Foo.h
class Foo{   static int Bar;};


Foo.cpp

int Foo::Bar = 0;
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
maybe this will work:

unsigned long Engine2D::(*ConvertToGraphicMode)(long, long, long);

edited:
- removed nonsense; me needs more sleep -

[Edited by - fnm on September 1, 2005 12:02:52 PM]
Try

unsigned long (*Engine2D::ConvertToGraphicMode)(long, long, long) = NULL;
At last it's working!!

ehh i forgot asterix :)

Thanks!!!!
Ok .. here's another problem:

(it's a bit simplified)

class Engine2D{private:  void DrawLine16(long x,long y);  void DrawLine32(long x,long y);public:  void (*DrawLine)(long x,long y);   void whatever()                          {         DrawLine = DrawLine16;        }}


And ones again error pops :
"c:\3D Engine\Source\Engine2D.cpp(143) : error C2440: '=' : cannot convert from 'void (__thiscall Engine2D::* )(long,long,long,long,D3DCOLOR)' to 'void (__cdecl *)(long,long,long,long,D3DCOLOR)'
There is no context in which this conversion is possible"


Any idea?

Try declaring your function pointer like this:
void (Engine2D::*DrawLine)(long x,long y); 
It's no good

says:
"c:\3D Engine\Source\Engine2D.cpp(11) : error C2350: 'Engine2D::DrawLine' is not a static member"

Edit: Here's the real code :)

class Engine2D{    private:        unsigned long                 screenLenght           ; // Screen lenght (resolution)        unsigned long                 screenHeight           ; // Screen height (resolution)        unsigned long                 screenDepth            ; // Bits per pixel        D3DFORMAT                     screenFormat           ; // Bits per pixel that are used         unsigned long                 i                      ; // Index variable to use in "for" loops         unsigned long                 j                      ; // Index variable to use in "for" loops         unsigned long                 k                      ; // Index variable to use in "for" loops        HRESULT                       hResultGlobal          ;                Rect                          clipRect               ;          LPDIRECT3D9                   d3d                    ;        LPDIRECT3DDEVICE9             d3dDevice              ;        IDirect3DSurface9*            backbuffer             ;        IDirect3DSurface9*            paintSurface           ;        RECT                          destBack               ;        D3DLOCKED_RECT                lockedRect             ;        D3DVIEWPORT9                  viewPort               ;        long                          pitch                  ;                                    unsigned long                 *videoBuffer32         ;        unsigned short                *videoBuffer16         ;                                                                             LogFile                       *gameLog               ;        long                          errorLog               ;        long                          eventLog               ;        long                          screenLog              ;    private:                                                       long                        ClipLine(long &x1,long &y1,long &x2,long &y2);        void                        DrawLine16(long x0, long y0, long x1, long y1,D3DCOLOR color);        void                        DrawLine32(long x0, long y0, long x1, long y1,D3DCOLOR color);        static unsigned long        (*ConvertToGraphicMode)(long red, long green, long blue);        static inline unsigned long RGB555(long red, long green, long blue)        {            return (((red & 31)<< 10 )+((green & 31)<< 5)+(blue % 31));        }        static inline unsigned long RGB565(long red, long green, long blue)        {            return (((red & 31) << 11) + ((green & 63) << 5) + (blue & 31));        }        static inline unsigned long RGB888(long red, long green, long blue)        {            return (((red & 255) << 16) + ((green & 255) << 8) + (blue & 255));        }        static inline unsigned long RGB101010(long red, long green, long blue)        {            return (((red & 1024) << 20) + ((green & 1024) << 10) + (blue & 1024));        }        static inline unsigned long RGB101010ToRGB555(long red,long green,long blue)        {            long r = red   >> 5;            long g = green >> 5;            long b = blue  >> 5;                        return LongToRGB(r,g,b);        }        static inline unsigned long RGB101010ToRGB565(long red,long green,long blue)        {            long r = red   >> 5;            long g = green >> 4;            long b = blue  >> 5;            return LongToRGB(r,g,b);        }        static inline unsigned long RGB101010ToRGB888(long red,long green,long blue)        {            long r = red   >> 2;            long g = green >> 2;            long b = blue  >> 2;            return LongToRGB(r,g,b);        }        static inline unsigned long RGB101010ToRGB101010(long red,long green,long blue)        {            long r = red   ;            long g = green ;            long b = blue  ;            return LongToRGB(r,g,b);        }    public:        Engine2D();        ~Engine2D();                long          SetLogFile(LogFile *gLog,long erLog,long evLog,long sLog);        long          InitEngine(unsigned long sLenght, unsigned long sHeight, unsigned long bbp,HWND mainWindowHandle);        long          BegineDrawing();        void          EndDrawing();        void          Present();        void          ClearCanvas(D3DCOLOR col);        void          (*DrawLine)(long x0, long y0, long x1, long y1,D3DCOLOR color);        void          DrawClipLine(long x0, long y0, long x1, long y1,D3DCOLOR color);        void inline   PlotPixel(long x,long y,D3DCOLOR col);                   static unsigned long (*LongToRGB)(long red, long green, long blue);        static inline unsigned long RGB444ToGraphicMode(long red,long green ,long blue)            {                   return ConvertToGraphicMode(red*64, green*64, blue*64);            }        static inline unsigned long RGB444ToGraphicMode(unsigned long color)            {            long red   = ((color & 0x0f00) >> 8);            long green = ((color & 0x00f0) >> 4);            long blue  = (color & 0x000f);            return ConvertToGraphicMode(red*64, green*64, blue*64);            }        static inline unsigned long RGB555ToGraphicMode(long red,long green ,long blue)            {            return ConvertToGraphicMode(red*32, green*32, blue*32);            }        static inline unsigned long RGB555ToGraphicMode(unsigned long color)            {             long red   = ((color & 0x7C00) >> 10);            long green = ((color & 0x03E0) >> 5);            long blue  = ( color & 0x001F);            return ConvertToGraphicMode(red*32, green*32, blue*32);            }        static inline unsigned long RGB565ToGraphicMode(long red,long green ,long blue)            {            return ConvertToGraphicMode(red*32, green*16, blue*32);            }              static inline unsigned long RGB565ToGraphicMode(unsigned long color)            {            long red   = ((color & 0xF800) >> 11);            long green = ((color & 0x07E0) >> 6);            long blue  = ( color & 0x001F);              return ConvertToGraphicMode(red*32, green*16, blue*32);            }        static inline unsigned long RGB888ToGraphicMode(long red,long green ,long blue)            {            return ConvertToGraphicMode(red*4, green*4, blue*4);            }        static inline unsigned long RGB888ToGraphicMode(unsigned long color)            {            long red   = ((color & 0xFF0000) >> 16);            long green = ((color & 0x00FF00) >> 8);            long blue  = ( color & 0x0000FF);              return ConvertToGraphicMode(red*4, green*4, blue*4);            }        static inline unsigned long RGB101010ToGraphicMode(long red,long green ,long blue)            {            return ConvertToGraphicMode(red, green, blue);            }        static inline unsigned long RGB101010ToGraphicMode(unsigned long color)            {            long red   = ((color & 0x3FF00000) >> 20);            long green = ((color & 0x000FFC00) >> 10);            long blue  = ( color & 0x000003FF);              return ConvertToGraphicMode(red, green, blue);            }      };


A pointer to a (non-static) class member is not the same thing as a pointer to a non-class member (or to a static class member). Compare the types in the error message:

error C2440: '=' : cannot convert from 'void (__thiscall Engine2D::* )(long,long,long,long,D3DCOLOR)'                                     to 'void (__cdecl *)              (long,long,long,long,D3DCOLOR)'


"ordinary" C++ functions use the C calling convention, marked by the __cdecl qualifier.
Member functions use a different calling convention, marked by the __thiscall qualifier.

They can't mix.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Hmm i noticed that this qualifiers ware diferent but i didn't know why though.

I'll read this FAQ.

Thanks for your help!!

This topic is closed to new replies.

Advertisement