digitalmars.D - Undefined (Win32) Externals
- Loopback (31/31) Jun 12 2011 Hi!
- Andrej Mitrovic (13/13) Jun 12 2011 Use the WindowsAPI bindings from here:
- Loopback (4/17) Jun 12 2011 Great, thanks for the link!
- Andrej Mitrovic (22/22) Jun 12 2011 Well most API functions stay the same for a long time on Windows.
- Jonathan M Davis (4/46) Jun 12 2011 I believe that you need extern(C) around those functions. They're C func...
Hi! Let me begin by saying, that I haven't used Usenet newsgroup at all, so please excuse me for any errors or misunderstandings of the guidelines. I recently begun programming a win32 application though I instantly got stuck with a problem. As you might know, win32 applications require that you define the WindowProc function for processing window messages. I've used a object-oriented approach for this, and that requires that you declare the WindowProc function as static, and bind your own class (hWnd) to GWL_USERDATA, to be able to call your own, class defined, message handler (WindowProc). To do this, you have to access the two functions GetWindowLong and SetWindowLong. For some reason, these functions do not exist in the windows module (std.c.windows.windows), neither does the GWL_USERDATA constant. To solve this I've used this alternative code: extern (Windows) { int GWL_USERDATA; LONG SetWindowLong(HWND, int, LONG); LONG GetWindowLong(HWND, int); } When I then try to compile this application, the GWL_USERDATA constant compiles without any errors, but the Get-/SetWindowLong produces linker errors. To solve the linker errors, I checked which library they were contained in, on MSDN it said User32.lib. Therefore I linked to this library - without any success. So to summarize, how do I solve these linker errors: Error 42: Symbol Undefined _SetWindowLong 12 Error 42: Symbol Undefined _GetWindowLong 8 Sorry for such a long message! Any help is greatly appreciated!
Jun 12 2011
Use the WindowsAPI bindings from here: http://dsource.org/projects/bindings/wiki/WindowsApi Pass -version=Unicode and various other version specifiers based on what you need. Otherwise, a typical Win32 example looks like this: http://codepad.org/cP2XrrHS For what it's worth, I will (hopefully) soon publish D translated examples from the Programming Windows book, by Charles Petzold. It contains about 145 examples (a few dozen were left out in the D translation because they covered 8-bit displays which don't exist anymore). But I have yet to receive an e-mail back from Petzold regarding the copyright/licensing of his code. Until I get back from him, I can't publish the code.
Jun 12 2011
On 2011-06-13 00:50, Andrej Mitrovic wrote:Use the WindowsAPI bindings from here: http://dsource.org/projects/bindings/wiki/WindowsApi Pass -version=Unicode and various other version specifiers based on what you need. Otherwise, a typical Win32 example looks like this: http://codepad.org/cP2XrrHS For what it's worth, I will (hopefully) soon publish D translated examples from the Programming Windows book, by Charles Petzold. It contains about 145 examples (a few dozen were left out in the D translation because they covered 8-bit displays which don't exist anymore). But I have yet to receive an e-mail back from Petzold regarding the copyright/licensing of his code. Until I get back from him, I can't publish the code.Great, thanks for the link! Though I do have to ask, are these bindings any mature? Most of the files in the SVN repository are about 4 years old.
Jun 12 2011
Well most API functions stay the same for a long time on Windows. Examples compiled in 1998 for Windows 98 will compile in 2011 for Windows 7, and they will both run fine. At least the simple ones will. The bindings /might/ be missing some new vista/win7 function prototypes but I'm not sure if that's true or not. And if you use vista/win7 features exclusively, you can say goodbye to compatibility with pre-vista systems (if you care about that). I'm not sure why your example is not compiling for you, it does for me: import std.c.windows.windows; extern (Windows) { int GWL_USERDATA; LONG SetWindowLong(HWND, int, LONG); LONG GetWindowLong(HWND, int); } void main() { } But try replacing the prototypes with this (notice the A at the end): LONG SetWindowLongA(HWND, int, LONG); LONG GetWindowLongA(HWND, int); Which DMD version are you running?
Jun 12 2011
On 2011-06-13 01:53, Andrej Mitrovic wrote:Well most API functions stay the same for a long time on Windows. Examples compiled in 1998 for Windows 98 will compile in 2011 for Windows 7, and they will both run fine. At least the simple ones will. The bindings /might/ be missing some new vista/win7 function prototypes but I'm not sure if that's true or not. And if you use vista/win7 features exclusively, you can say goodbye to compatibility with pre-vista systems (if you care about that). I'm not sure why your example is not compiling for you, it does for me: import std.c.windows.windows; extern (Windows) { int GWL_USERDATA; LONG SetWindowLong(HWND, int, LONG); LONG GetWindowLong(HWND, int); } void main() { } But try replacing the prototypes with this (notice the A at the end): LONG SetWindowLongA(HWND, int, LONG); LONG GetWindowLongA(HWND, int); Which DMD version are you running?Replacing them with their ASCII variants worked flawlessly! Though GWL_USERDATA is apparently undefined (0). To solve this I had to declare the variable explicitly: const int GWL_USERDATA = -21; About the WindowsAPI binding, is it fully functional for D2, since it seems to have been inactive for so long? Even though I've solved this error (Set-/GetWindowLong) I've got stuck with another error (this might be off topic, perhaps a new thread?) related to DirectX. At the moment I'm using the DDirectX9 binding (at dsource.org). So far it's been working perfectly fine, everything compiles and no linker errors, but I do have problems with creating the Direct3D9 Device. The reason I am asking this here (and not in a forum related to DirectX) is because there are no debug outputs, even with the DirectX debug DLLs, I guess this is related to the D debugger or the wrapper? To get to the problem, in my code, I set up a Win32 Window like this: // Window Properties WNDCLASSA wnd; // Setup The Properties wnd.style = CS_HREDRAW | CS_VREDRAW; wnd.lpfnWndProc = &WindowProc; wnd.hInstance = hInstance; wnd.lpszClassName = "CWindow"; // Register Class RegisterClassA(&wnd); // Create Window m_hWnd = CreateWindowA("CWindow", "Win32&DirectX Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, null, null, hInstance, null); // Used for static WindowProc SetWindowLongA(m_hWnd, GWL_USERDATA, cast(LONG)(cast(void*) this)); // Show & Update The Window ShowWindow(m_hWnd, SW_SHOW); UpdateWindow(m_hWnd); After this, I set up the direct3d environment with this code: // Create Direct3D Interface m_d3d = Direct3DCreate9(D3D_SDK_VERSION); // <--- This is successful // Present Parameters D3DPRESENT_PARAMETERS d3dpp = {0}; // Setup the options d3dpp.Windowed = true; d3dpp.SwapEffect = D3DSWAPEFFECT.D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = m_hWnd; // Create Direct3D Device HRESULT hr = m_d3d.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE.D3DDEVTYPE_HAL, m_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_d3dDevice); if(FAILED(hr)) MessageBoxA(null, "Failurreeeee", "Majs", MB_ICONERROR); The HRESULT from CreateDevice always returns the following: HRESULT: 0x8876086c (2289436780) Name: D3DERR_INVALIDCALL Description: Invalid call Severity code: Failed Facility Code: FACILITY_D3D (2166) Error Code: 0x086c (2156) I've googled this a lot with no avail, and since my code is so small, I'm afraid it's related to D or the DirectX Wrapper. I've tried to play a bit with the d3dpresent parameters without success... Once again, I'm sorry if it's inconvenient to post this here, although this seems like the most appropriate place. (if worth noticing, I'm using DMD Version 2.052 and the wrapper is D1)
Jun 12 2011
On 2011-06-13 03:54, Loopback wrote:On 2011-06-13 01:53, Andrej Mitrovic wrote:I've found a solution to the problem, though not the reason. Would be great if someone could explain. However, using only this code: d3dpp.Windowed = true; d3dpp.SwapEffect = D3DSWAPEFFECT.D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = m_hWnd; The CreateDevice functions throws an D3DERR_INVALIDCALL error. To avoid this, you have to specify every single parameter individually, etc. This code worked flawlessly for me (Windowed Mode): D3DPRESENT_PARAMETERS d3dpp = {0, 0, D3DFMT_UNKNOWN, 1, D3DMULTISAMPLE_NONE, 0, D3DSWAPEFFECT_DISCARD, m_hWnd, TRUE, FALSE, 0, 0, 0, 0 }; No what I am wondering is this; how come this works but not the other code snippet? These are more or less equal except that I don't use the initializer construct for one of the snippets.Well most API functions stay the same for a long time on Windows. Examples compiled in 1998 for Windows 98 will compile in 2011 for Windows 7, and they will both run fine. At least the simple ones will. The bindings /might/ be missing some new vista/win7 function prototypes but I'm not sure if that's true or not. And if you use vista/win7 features exclusively, you can say goodbye to compatibility with pre-vista systems (if you care about that). I'm not sure why your example is not compiling for you, it does for me: import std.c.windows.windows; extern (Windows) { int GWL_USERDATA; LONG SetWindowLong(HWND, int, LONG); LONG GetWindowLong(HWND, int); } void main() { } But try replacing the prototypes with this (notice the A at the end): LONG SetWindowLongA(HWND, int, LONG); LONG GetWindowLongA(HWND, int); Which DMD version are you running?Replacing them with their ASCII variants worked flawlessly! Though GWL_USERDATA is apparently undefined (0). To solve this I had to declare the variable explicitly: const int GWL_USERDATA = -21; About the WindowsAPI binding, is it fully functional for D2, since it seems to have been inactive for so long? Even though I've solved this error (Set-/GetWindowLong) I've got stuck with another error (this might be off topic, perhaps a new thread?) related to DirectX. At the moment I'm using the DDirectX9 binding (at dsource.org). So far it's been working perfectly fine, everything compiles and no linker errors, but I do have problems with creating the Direct3D9 Device. The reason I am asking this here (and not in a forum related to DirectX) is because there are no debug outputs, even with the DirectX debug DLLs, I guess this is related to the D debugger or the wrapper? To get to the problem, in my code, I set up a Win32 Window like this: // Window Properties WNDCLASSA wnd; // Setup The Properties wnd.style = CS_HREDRAW | CS_VREDRAW; wnd.lpfnWndProc = &WindowProc; wnd.hInstance = hInstance; wnd.lpszClassName = "CWindow"; // Register Class RegisterClassA(&wnd); // Create Window m_hWnd = CreateWindowA("CWindow", "Win32&DirectX Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, null, null, hInstance, null); // Used for static WindowProc SetWindowLongA(m_hWnd, GWL_USERDATA, cast(LONG)(cast(void*) this)); // Show & Update The Window ShowWindow(m_hWnd, SW_SHOW); UpdateWindow(m_hWnd); After this, I set up the direct3d environment with this code: // Create Direct3D Interface m_d3d = Direct3DCreate9(D3D_SDK_VERSION); // <--- This is successful // Present Parameters D3DPRESENT_PARAMETERS d3dpp = {0}; // Setup the options d3dpp.Windowed = true; d3dpp.SwapEffect = D3DSWAPEFFECT.D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = m_hWnd; // Create Direct3D Device HRESULT hr = m_d3d.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE.D3DDEVTYPE_HAL, m_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_d3dDevice); if(FAILED(hr)) MessageBoxA(null, "Failurreeeee", "Majs", MB_ICONERROR); The HRESULT from CreateDevice always returns the following: HRESULT: 0x8876086c (2289436780) Name: D3DERR_INVALIDCALL Description: Invalid call Severity code: Failed Facility Code: FACILITY_D3D (2166) Error Code: 0x086c (2156) I've googled this a lot with no avail, and since my code is so small, I'm afraid it's related to D or the DirectX Wrapper. I've tried to play a bit with the d3dpresent parameters without success... Once again, I'm sorry if it's inconvenient to post this here, although this seems like the most appropriate place. (if worth noticing, I'm using DMD Version 2.052 and the wrapper is D1)
Jun 14 2011
On 2011-06-12 15:39, Loopback wrote:Hi! Let me begin by saying, that I haven't used Usenet newsgroup at all, so please excuse me for any errors or misunderstandings of the guidelines. I recently begun programming a win32 application though I instantly got stuck with a problem. As you might know, win32 applications require that you define the WindowProc function for processing window messages. I've used a object-oriented approach for this, and that requires that you declare the WindowProc function as static, and bind your own class (hWnd) to GWL_USERDATA, to be able to call your own, class defined, message handler (WindowProc). To do this, you have to access the two functions GetWindowLong and SetWindowLong. For some reason, these functions do not exist in the windows module (std.c.windows.windows), neither does the GWL_USERDATA constant. To solve this I've used this alternative code: extern (Windows) { int GWL_USERDATA; LONG SetWindowLong(HWND, int, LONG); LONG GetWindowLong(HWND, int); } When I then try to compile this application, the GWL_USERDATA constant compiles without any errors, but the Get-/SetWindowLong produces linker errors. To solve the linker errors, I checked which library they were contained in, on MSDN it said User32.lib. Therefore I linked to this library - without any success. So to summarize, how do I solve these linker errors: Error 42: Symbol Undefined _SetWindowLong 12 Error 42: Symbol Undefined _GetWindowLong 8 Sorry for such a long message! Any help is greatly appreciated!I believe that you need extern(C) around those functions. They're C functions, not D functions. - Jonathan M Davis
Jun 12 2011
On 2011-06-13 01:16, Jonathan M Davis wrote:On 2011-06-12 15:39, Loopback wrote:Thanks for you reply though linker errors (Symbol Undefined) are still generated even though I've specified the functions as external C.Hi! Let me begin by saying, that I haven't used Usenet newsgroup at all, so please excuse me for any errors or misunderstandings of the guidelines. I recently begun programming a win32 application though I instantly got stuck with a problem. As you might know, win32 applications require that you define the WindowProc function for processing window messages. I've used a object-oriented approach for this, and that requires that you declare the WindowProc function as static, and bind your own class (hWnd) to GWL_USERDATA, to be able to call your own, class defined, message handler (WindowProc). To do this, you have to access the two functions GetWindowLong and SetWindowLong. For some reason, these functions do not exist in the windows module (std.c.windows.windows), neither does the GWL_USERDATA constant. To solve this I've used this alternative code: extern (Windows) { int GWL_USERDATA; LONG SetWindowLong(HWND, int, LONG); LONG GetWindowLong(HWND, int); } When I then try to compile this application, the GWL_USERDATA constant compiles without any errors, but the Get-/SetWindowLong produces linker errors. To solve the linker errors, I checked which library they were contained in, on MSDN it said User32.lib. Therefore I linked to this library - without any success. So to summarize, how do I solve these linker errors: Error 42: Symbol Undefined _SetWindowLong 12 Error 42: Symbol Undefined _GetWindowLong 8 Sorry for such a long message! Any help is greatly appreciated!I believe that you need extern(C) around those functions. They're C functions, not D functions. - Jonathan M Davis
Jun 12 2011
On Jun 13, 11 07:16, Jonathan M Davis wrote:On 2011-06-12 15:39, Loopback wrote:extern(Windows) is correct since they have WINAPI calling convention. The problem is their actual names are Get/SetWindowLongW/A...Hi! Let me begin by saying, that I haven't used Usenet newsgroup at all, so please excuse me for any errors or misunderstandings of the guidelines. I recently begun programming a win32 application though I instantly got stuck with a problem. As you might know, win32 applications require that you define the WindowProc function for processing window messages. I've used a object-oriented approach for this, and that requires that you declare the WindowProc function as static, and bind your own class (hWnd) to GWL_USERDATA, to be able to call your own, class defined, message handler (WindowProc). To do this, you have to access the two functions GetWindowLong and SetWindowLong. For some reason, these functions do not exist in the windows module (std.c.windows.windows), neither does the GWL_USERDATA constant. To solve this I've used this alternative code: extern (Windows) { int GWL_USERDATA; LONG SetWindowLong(HWND, int, LONG); LONG GetWindowLong(HWND, int); } When I then try to compile this application, the GWL_USERDATA constant compiles without any errors, but the Get-/SetWindowLong produces linker errors. To solve the linker errors, I checked which library they were contained in, on MSDN it said User32.lib. Therefore I linked to this library - without any success. So to summarize, how do I solve these linker errors: Error 42: Symbol Undefined _SetWindowLong 12 Error 42: Symbol Undefined _GetWindowLong 8 Sorry for such a long message! Any help is greatly appreciated!I believe that you need extern(C) around those functions. They're C functions, not D functions. - Jonathan M Davis
Jun 12 2011