digitalmars.D - Access violation when calling member function through pointer
- aleko (34/34) Apr 16 2005 Hi,
- Andrew Fedoniouk (45/90) Apr 16 2005 Well.... your are not alone, once per month this question arises :)
- aleko (7/12) Apr 19 2005 This seems very strange to me. I can see how this would effect local obj...
- Ben Hinkle (2/5) Apr 17 2005 and store to a MyWindow
- Ben Hinkle (4/6) Apr 17 2005 oh yeah - you are probably going to need something like
- aleko (6/9) Apr 19 2005 That was my initial idea. I was quite surprised when the compiler compla...
Hi, I have a window class with a static WndMain handler. After creating the window, I tag it with the address of the class instance so that WndProc knows which class instance to dispatch events to. When called, WndProc extracts the class pointer, and calls the appropriate event handler method. The problem is that when WndProc tries to dereference the "this" pointer an access violation occurs. Here's some code: class MyWindow { public: bool create() { // fill WNDCLASSA... // register class... // create window... SetWindowLong( _HWnd, GWL_USERDATA, cast(uint)&this ); } private: extern( Windows ) static uint WndProc( HWND hwnd, uint msg, uint lparam, uint wparam ) { // get address MyWindow *thisWnd = cast(MyWindow*)GetWindowLong( hwnd, GWL_USERDATA ); int result = 0; switch( msg ) { : thisWnd.onSomeEvent( 1, 2, 3 ); // Access violation! Why?? : } } } Thanks in advance, Aleko
Apr 16 2005
When called, WndProc extracts the class pointer, and calls the appropriate event handler method. The problem is that when WndProc tries to dereference the "this" pointer an access violation occurs.Well.... your are not alone, once per month this question arises :) The problem is that you are not storing Window reference in the place where "mark-n-sweeping" GC can reach it on "mark" stage. So your Window instance is getting deleted on "sweep" as it is not visible for D runtime thus your are trying to work with the instance which was destroyed already. One of the possible solutions is to use static global map ( 'all' below ) which maps HWND to correspondent Window instance class Window { HWND hWnd; ............. } Window[HWND] all; void createWindow(Window w) { w.hWnd = CreateWindowExW(0,cast(LPCWSTR)"DWindow",...., null); all[hWnd] = w.hWnd; } private Window self(HWND h) { Window *pw = h in all; if( pw !== null ) return *pw; return null; } extern(Windows) LRESULT DWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_SIZE: case WM_MOVE: { Window w = self(hWnd); if(w is null) break; } break; ..... } } Regards. Andrew. http://terrainformatica.com "aleko" <aleko_member pathlink.com> wrote in message news:d3ssu4$12av$1 digitaldaemon.com...Hi, I have a window class with a static WndMain handler. After creating the window, I tag it with the address of the class instance so that WndProc knows which class instance to dispatch events to. When called, WndProc extracts the class pointer, and calls the appropriate event handler method. The problem is that when WndProc tries to dereference the "this" pointer an access violation occurs. Here's some code: class MyWindow { public: bool create() { // fill WNDCLASSA... // register class... // create window... SetWindowLong( _HWnd, GWL_USERDATA, cast(uint)&this ); } private: extern( Windows ) static uint WndProc( HWND hwnd, uint msg, uint lparam, uint wparam ) { // get address MyWindow *thisWnd = cast(MyWindow*)GetWindowLong( hwnd, GWL_USERDATA ); int result = 0; switch( msg ) { : thisWnd.onSomeEvent( 1, 2, 3 ); // Access violation! Why?? : } } } Thanks in advance, Aleko
Apr 16 2005
Thanks, you pointed me in the right direction. It works now.The problem is that you are not storing Window reference in the place where "mark-n-sweeping" GC can reach it on "mark" stage. So your Window instance is getting deleted on "sweep" as it is not visible for D runtime thus your are trying to work with the instance which was destroyed already.This seems very strange to me. I can see how this would effect local objects, but the window instance remains referenced in WinMain where it is created. Another thing that puzzled me is the need to use the address-of operator on 'this', i.e. cast(uint)&this. Is 'this' a reference or a pointer? Thanks, Aleko
Apr 19 2005
SetWindowLong( _HWnd, GWL_USERDATA, cast(uint)&this );try "this" instead of "&this"MyWindow thisWnd = cast(MyWindow)cast(void*)GetWindowLong( hwnd, GWL_USERDATA );and store to a MyWindow
Apr 17 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:d3tgmd$1h4q$1 digitaldaemon.com...oh yeah - you are probably going to need something like cast(uint)cast(void*)this.SetWindowLong( _HWnd, GWL_USERDATA, cast(uint)&this );try "this" instead of "&this"
Apr 17 2005
That was my initial idea. I was quite surprised when the compiler complained that it couldn't convert from a MyWindow to a uint. It looked to me as if 'this' is a reference, and not a pointer.try "this" instead of "&this"oh yeah - you are probably going to need something like cast(uint)cast(void*)this.I hadn't though of that. For someone with a C++ background this is a bit of a stretch. Aleko
Apr 19 2005