PDA

View Full Version : Cannot load user32.dll from extern C file



been_1990
19th October 2010, 03:01
In a C file I load into my QT app:

extern "C"{
#include "raw_mouse.h"
}
When it tries to load user32.dll:

HMODULE user32 = LoadLibrary("user32.dll");
if (!user32) return 0;
It fails. Why?

Timoteo
19th October 2010, 03:53
What does GetLastError() say?

squidge
19th October 2010, 08:11
I think you'll find your application already has a dependency on user32.dll and so is already linked to your project - there's no need to load it again.

been_1990
19th October 2010, 12:24
If it is already linked, how can I assign it to (HMODULE user32)?

ChrisW67
19th October 2010, 23:37
Why do you need to?

squidge
20th October 2010, 10:03
What functions are you trying to use? Most already have thunks, so you can just call them directly.

been_1990
20th October 2010, 14:42
Why do you need to?
Because the rest of the C app needs HMODULE user32.

// Return 0 if rawinput is not available
HMODULE user32 = LoadLibrary("user32.dll");
if (!user32) return 0;
_RRID = (pRegisterRawInputDevices)GetProcAddress(user32,"RegisterRawInputDevices");
if (!_RRID) return 0;
_GRIDL = (pGetRawInputDeviceList)GetProcAddress(user32,"GetRawInputDeviceList");
if (!_GRIDL) return 0;
_GRIDIA = (pGetRawInputDeviceInfoA)GetProcAddress(user32,"GetRawInputDeviceInfoA");
if (!_GRIDIA) return 0;
_GRID = (pGetRawInputData)GetProcAddress(user32,"GetRawInputData");
if (!_GRID) return 0;

Timoteo
20th October 2010, 20:24
The library having been loaded by the pe loader already (quite possibly the case) will not make LoadLibrary fail. Again, what does GetLastError() say?

squidge
20th October 2010, 22:33
In a Windows application, I can just use RegisterRawInputDevices(), I've never needed to do LoadLibrary/GetProcAddress, as they are standard functions.

This is why I'm confused. It's a standard library.

Timoteo
20th October 2010, 22:45
I'm thinking that this code was originally written to allow an assembly program to use the interface too (meaning it's probably quite old). Assembly modules carry no implied dependencies, so the linker does not automatically bind to any external modules.

chris_helloworld
21st October 2010, 09:58
user32.dll should already be loaded and the msdn documentation doesn't actually specify what happens if you call LoadLibrary on a dll which is already loaded, though I see no reason why it would not work ok. Did you ever try using GetLastError ?

You can always try using GetModuleHandle to get the handle to the already loaded dll if you really do want to use GetProcAddress. (though I do agree with squidge that this really isn't necessary).

Chris.

Timoteo
21st October 2010, 15:52
the msdn documentation doesn't actually specify what happens if you call LoadLibrary on a dll which is already loaded

It does. It just takes a closer read.


The system maintains a per-process reference count on all loaded modules. Calling LoadLibrary increments the reference count.

been_1990
22nd October 2010, 19:30
You can always try using GetModuleHandle to get the handle to the already loaded dll if you really do want to use GetProcAddress.
If there is a better way I would definitely go for it.


Did you ever try using GetLastError ?
Yes:

qDebug() << init_raw_mouse(1, 0, 1) // Outputs 0;
qDebug() << GetLastError(); // Outputs 0

Here (http://developer.qt.nokia.com/forums/viewthread/502) they say that if I recompile QT passing -D _WIN32_WINNT=0×501 as arguments, I could filter WM_INPUT messages.
But I still would have to use that C file for the rest of the implementation(to get the different input's and their respective x & y axis).
How can I rebuild QT? Can that happen trough QtCreator? I have VS2010, but don't use it.

Added after 4 minutes:


In a Windows application, I can just use RegisterRawInputDevices(), I've never needed to do LoadLibrary/GetProcAddress, as they are standard functions.

This is why I'm confused. It's a standard library.

So if I included windows.h I could trim the code a bit? (I have no idea on Win32 programming.)

Added after 6 minutes:
The website I downloaded the demo was here (http://jstookey.com/arcade/rawmouse/). I'm including the whole app in the attachment.

squidge
22nd October 2010, 19:33
GetLastError returns the last error message, it must be called immediately after the function that has failed, with no other function calls in-between. This is not the case for your code (you even have a qDebug between them), so it's useless in this case.

Put the call after the LoadLibrary, assign it to a variable, and either output it there, or put a breakpoint and check the value in the debugger.

Timoteo
22nd October 2010, 19:35
Your call to GetLastError is too far away from the call site to be of any benefit (Qt is probably reseting it). You need to place the call immediately after a winapi call. In this case, it's a pain in the arse because that would require you to modify raw_mouse.cpp

been_1990
22nd October 2010, 19:44
Ok, I just saw I get some warnings:

E:/QT Projects/rawInput-build-desktop/../rawInput/raw_mouse.c:154: warning: passing argument 1 of 'LoadLibraryW' from incompatible pointer type
c:\qt\2010.05\mingw\bin\../lib/gcc/mingw32/4.4.0/../../../../include/winbase.h:1727: expected 'LPCWSTR' but argument is of type 'char *'

PS: Im trying to use GetLastError, but Im getting some problems fromQtCreator, so it will take a while.

Timoteo
22nd October 2010, 19:56
That's probably why. You have unicode defined, but the source (raw_mouse.cpp) is using ANSI. I'm guessing that LoadLibrary has been failing all along with "no such file or directory". To continue as you are, you need to set your project up to use single-byte characters or you can patch raw_mouse.cpp to use the _TEXT() macro around the string literals. (e.g. _TEXT("user32.dll")).

Edit: After looking at it again, I can see that "char" is used too extensively to bother making it unicode compliant. Unless you have a compelling reason otherwise, you would be better served to just use ANSI encoding.

been_1990
22nd October 2010, 20:07
How do I set the rest of my application to ANSI?

Edit:
GetLastError() outputs '5716627'.

squidge
22nd October 2010, 20:34
5716627 doesn't sound like a valid error code, how do you get that?

wysota
22nd October 2010, 20:39
Sorry to cut into the discussion but wouldn't it be simpler to rewrite this init_raw_mouse function to do the following instead of the "LoadLibrary" part?


_RRID = RegisterRawInputDevices;
if (!_RRID) return 2;
_GRIDL = GetRawInputDeviceList;
if (!_GRIDL) return 3;
_GRIDIA = GetRawInputDeviceInfoA;
if (!_GRIDIA) return 33;
_GRID = GetRawInputData;
if (!_GRID) return 4;

The rest of the code could stay the same.

been_1990
22nd October 2010, 21:06
Yeah... Wise Wysota made it Work... Thanks! That solves the problem . Thanks to Timoteo and Squidge for helping.