When you create a DLL project under Code::Blocks, two files are generated:
- main.h: file with macros, includes and other stuff;
- main.cpp: code of the DllMain and exported functions.
main.h
#ifndef __MAIN_H__ #define __MAIN_H__ #include <windows.h> /* To use this exported function of dll, include this header * in your project. */ #ifdef BUILD_DLL #define DLL_EXPORT __declspec(dllexport) #else #define DLL_EXPORT #endif #ifdef __cplusplus extern "C" { #endif void DLL_EXPORT SomeFunction(const LPCSTR sometext); #ifdef __cplusplus } #endif #endif // __MAIN_H__
main.cpp
#include "main.h" // a sample exported function void DLL_EXPORT SomeFunction(const LPCSTR sometext) { MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION); } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: // attach to process // return FALSE to fail DLL load break; case DLL_PROCESS_DETACH: // detach from process break; case DLL_THREAD_ATTACH: // attach to thread break; case DLL_THREAD_DETACH: // detach from thread break; } return TRUE; // succesful }
Though our DLL exports correctly the "SomeFunction" function, the DllMain is not called when the library is loaded (by linking or dynamic loading using the LoadLibrary() function).
The solution consists in adding the following directives which wrap the DllMain code:
#ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif
Otherwise, just rename the main.cpp file into main.c! The problem is due to the fact that the DllMain function must not escape to the extern C rule; it's ok for the "SomeFunction" function, but DllMain has to be treated too!
Now you may try the following code:
main.cpp
#include "main.h" // a sample exported function void DLL_EXPORT SomeFunction(const LPCSTR sometext) { MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION); } #ifdef __cplusplus extern "C" { #endif BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: // attach to process // return FALSE to fail DLL load MessageBox(0, "Hello world!", "Message from DllMain", 0); break; case DLL_PROCESS_DETACH: // detach from process break; case DLL_THREAD_ATTACH: // attach to thread break; case DLL_THREAD_DETACH: // detach from thread break; } return TRUE; // succesful } #ifdef __cplusplus } #endif
This was just a little trick that I wish I could remember later.
Enjoy!
Ge0
No comments:
Post a Comment