digitalmars.D - Access violation after inheriting.
- Zarathustra (131/131) Oct 19 2009 Could somebody explain memory rules in class inheriting?
- Walter Bright (1/1) Oct 19 2009 Try compiling with -gc and run it under the debugger.
- Daniel Keep (13/99) Oct 19 2009 imports are private by default.
Could somebody explain memory rules in class inheriting? The following code illustrates my problem, look at 'main' function: //____________________________________________ module window; private import base; private import structs; private static import user32; private static import kernel32; private static import gdi32; private: extern (Windows) dword wndProc(ptr o_hwnd, dword o_msg, dword o_wparam, dword o_lparam){ alias user32.EWindowMessage WM; auto l_wnd = cast(Window*)user32.getWindowLong(o_hwnd, 0x00); if(o_msg == WM.NCCREATE){ user32.setWindowLong(o_hwnd, 0x00, *(cast(dword*)o_lparam)); } else if(l_wnd is null){ return 0x00; } return (cast(Window*)user32.getWindowLong(o_hwnd, 0x00)).wndProc(o_hwnd, o_msg, o_wparam, o_lparam); } public: class Window{ private const ptr handle; void onMouseDown (MouseEventArgs o_mea){ } this(){ WINWndClassEx wndClass; wndClass.size = 0x00000030; wndClass.style = 0x00000003; wndClass.wndProc = cast(ptr)&.wndProc; wndClass.clsExtraBytes = 0x00000000; wndClass.wndExtraBytes = 0x00000004; wndClass.hInstance = kernel32.getModuleHandle(null); wndClass.hIcon = user32.loadIcon(null, 0x00007F00); wndClass.hCursor = user32.loadCursor(null, 0x00007F00); wndClass.hbrBackground = gdi32.getStockObject(0x00000000); wndClass.menuName = null; wndClass.className = cast(wstr)"clsname"; wndClass.hIconSm = user32.loadIcon(null, 0x00007F00); if(!user32.registerClassEx(cast(ptr)&wndClass)){ if(kernel32.getLastError() != 0x0582){ user32.messageBox(null, user32.translateErrorCode(kernel32.getLastError()), cast(wstr)"error", 0x00000000); assert(false, "window class registering failed"); } } handle = user32.createWindowEx( 0, wndClass.className, cast(wstr)"<applicationcaption>", 0x00CF0000, 0x00000000, 0x00000000, 0x00000280, 0x000001E0, null, null, kernel32.getModuleHandle(null), cast(ptr)&this ); if(handle is null){ user32.messageBox(null, user32.translateErrorCode(kernel32.getLastError()), cast(wstr)"error", 0x00000000); assert(false, "window creating failed"); } } public void run(){ WINMsg msg; user32.showWindow(handle, 0x0000000A); user32.updateWindow(handle); while(user32.getMessage(cast(ptr)&msg, null, 0, 0)){ user32.translateMessage(cast(ptr)&msg); user32.dispatchMessage(cast(ptr)&msg); } } private dword wndProc(ptr o_hwnd, dword o_msg, dword o_wparam, dword o_lparam){ alias user32.EWindowMessage WM; alias user32.EMouseKey WK; switch(o_msg){ case WM.DESTROY: user32.postQuitMessage(0x00); break; case WM.LBUTTONDOWN: MouseEventArgs l_mea; l_mea.button = MouseButton.LEFT; l_mea.location.x = loword(o_lparam); l_mea.location.x = hiword(o_lparam); onMouseDown(l_mea); break; case WM.RBUTTONDOWN: MouseEventArgs l_mea; l_mea.button = MouseButton.RIGHT; l_mea.location.x = loword(o_lparam); l_mea.location.x = hiword(o_lparam); onMouseDown(l_mea); break; default: return user32.defWindowProc(o_hwnd, o_msg, o_wparam, o_lparam); } return 0; } } //____________________________________________ module main: // ... class MyWindow : Window{ this(){ super(); } override void onMouseDown(MouseEventArgs o_mea){ MsgBox(cast(char[])"Hello"); } } void main(){ try{ Window wnd = new Window(); MyWindow mywnd = new MyWindow(); wnd .run(); // ok mywnd.run(); // access violation onClick } catch(Object o){ MsgBox(cast(char[])o.toString); } } //____________________________________________
Oct 19 2009
Try compiling with -gc and run it under the debugger.
Oct 19 2009
Zarathustra wrote:Could somebody explain memory rules in class inheriting? The following code illustrates my problem, look at 'main' function:Posts like this belong on d.learn.//____________________________________________ module window; private import base; private import structs; private static import user32; private static import kernel32; private static import gdi32;imports are private by default.private: extern (Windows) dword wndProc(ptr o_hwnd, dword o_msg, dword o_wparam, dword o_lparam){ alias user32.EWindowMessage WM; auto l_wnd = cast(Window*)user32.getWindowLong(o_hwnd, 0x00); if(o_msg == WM.NCCREATE){ user32.setWindowLong(o_hwnd, 0x00, *(cast(dword*)o_lparam)); } else if(l_wnd is null){ return 0x00; } return (cast(Window*)user32.getWindowLong(o_hwnd, 0x00)).wndProc(o_hwnd, o_msg, o_wparam, o_lparam); }You shouldn't be using Window*: see below.public: class Window{ private const ptr handle; void onMouseDown (MouseEventArgs o_mea){ } this(){ WINWndClassEx wndClass; wndClass.size = 0x00000030; wndClass.style = 0x00000003; wndClass.wndProc = cast(ptr)&.wndProc;What is ptr? If it's void*, you don't need to do this. Incidentally, there's already a set of bindings for the Win32 api. Not sure where the current version is; somewhere on dsource.org.wndClass.clsExtraBytes = 0x00000000; wndClass.wndExtraBytes = 0x00000004; wndClass.hInstance = kernel32.getModuleHandle(null); wndClass.hIcon = user32.loadIcon(null, 0x00007F00); wndClass.hCursor = user32.loadCursor(null, 0x00007F00); wndClass.hbrBackground = gdi32.getStockObject(0x00000000); wndClass.menuName = null; wndClass.className = cast(wstr)"clsname";Easier to type "clsname"w than cast(wstr)"clsname"wndClass.hIconSm = user32.loadIcon(null, 0x00007F00); ... handle = user32.createWindowEx( 0, wndClass.className, cast(wstr)"<applicationcaption>", 0x00CF0000, 0x00000000, 0x00000000, 0x00000280, 0x000001E0, null, null, kernel32.getModuleHandle(null), cast(ptr)&this );this is a reference to the object. &this is the address at which the reference is being stored, which is probably *on the stack*. I wouldn't be surprised if this is why it's segfaulting.if(handle is null){ user32.messageBox(null, user32.translateErrorCode(kernel32.getLastError()), cast(wstr)"error", 0x00000000); assert(false, "window creating failed"); } } ... class MyWindow : Window{ this(){ super(); } override void onMouseDown(MouseEventArgs o_mea){ MsgBox(cast(char[])"Hello");Unless MsgBox is defined very strangely, the cast(char[]) here should be superfluous.} } ...
Oct 19 2009