My program needs to install a windows hook (SetWindowsHookEx), so I created a DLL with the necessary code and everything compiled fine. In my main program, I used LoadLibrary to load the DLL and GetProcAddress to retrieve the function's address. LoadLibrary works fine, but GetProcAddress always fails. GetLastError returns ERROR_PROC_NOT_FOUND.
I did this type of thing many times before using Dev-C++ and never had problems. What on earth am I doing wrong?
Have you exported your function?
For GCC you can export all symbols automatically by adding --export-all-symbols (duh) to the linker options.
I wen't to the Project's build options, clicked on the Linker tab, and added --export-all-symbols, and it still didn't work. I've also made sure I haven't misspelled the function name for GetProcAddress, so that can't be it.
The function looks like this:
DLL_EXPORT LRESULT CALLBACK CBTProc(int code, WPARAM wParam, LPARAM lParam) {
// my code here.
}
and here is the code that trys to load it:
dllInst = LoadLibrary("loader.dll");
if (dllInst != NULL) {
cbtProc = (HOOKPROC) GetProcAddress(dllInst, "CBTProc");
if (cbtProc != NULL) {
cbtHook = SetWindowsHookEx(WH_CBT, cbtProc, dllInst, tId);
}
}
Hmm... this looks like Joe Normal's standard keylogger template number 34... should certainly work.
Ok, so I'm not the best programmer in the world. I mainly do it for fun. Does anyone have any ideas on what's going on?
No, no... I did not mean it that way. I meant to say that this is the "school book way" or "cook book way" of installing a hook, just like you will probably find it on MSDN -- so it should certainly work.
You don't happen to strip the library?
It's not striped. I wen't to the build options and the only thing I checked was Optimize generated code (for size).
Do you know for certain "DLL_EXPORT" is defined as "__declspec(dllexport)"?
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT
#endif
and yes, BUILD_DLL is defined.
I did this many times with Dev-C++ before without any issues, so I figure its some option in Code::Blocks that I'm missing, except I can't figure out what it is.
You should post the complete build log for the library, so we can see what options are passed to the compiler/linker (set logging to "full commandline" in compiler options if you haven't done so anyway).
Project : DLL Sample
Compiler : GNU GCC Compiler (called directly)
Directory : C:\Program Files\CodeBlocks\Projects\sss\dll\
--------------------------------------------------------------------------------
Switching to target: default
mingw32-gcc.exe -Os -DBUILD_DLL -Os -DBUILD_DLL -I"C:\Program Files\CodeBlocks\include" -c main.c -o .objs\main.o
mingw32-g++.exe -shared -Wl,--dll -L"C:\Program Files\CodeBlocks\lib" .objs\main.o -o loader.dll --export-all-symbols
Process terminated with status 0 (0 minutes, 0 seconds)
0 errors, 0 warnings
Can't see anything wrong :(
QuotedllInst = LoadLibrary("loader.dll");
Maybe it's picking up a loader.dll from somewhere else? Can you try giving there the full path to your loader.dll?
Do you compile the file as a C file? If not, are you using "extern "c"" to avoid the c++ name mangling?
extern "C"
{
DLL_EXPORT LRESULT CALLBACK CBTProc(int code, WPARAM wParam, LPARAM lParam)
{
// my code here.
}
}
If this still does not resolve your problem, go look inside the .def file what is the real name for the exported function. In my experience, CALLBACK functions are always exported with "@16 " at the end, for example:
CBTProc exported as CBTProc@16
and so on.
THANK YOU KKEZ!!!
Actually, according to the .def file, it is CBTProc@12. So I called GetProcAddress(dllInst, "CBTProc@12") and everything went perfectly! Thanks again!