Olympus
asked on
Dynamic DLL loading problem
Whats wrong with this? The pInitialize pointer is never set to the correct function and i get the "plugin not loaded" debug message box...
Client code:
typedef char *(__stdcall *plspInitialize)(void *);
typedef void (__stdcall *plspCleanup)(void);
typedef void (__stdcall *plspParseMsg)(unsigned short, unsigned short, char **, unsigned long *);
HMODULE Handle;
Handle = LoadLibrary("Plugins\\srv_ capture.dl l");
if (Handle != 0) {
plspInitialize pInitialize = (plspInitialize)GetProcAdd ress(Handl e, "lspInitialize");
plspCleanup pCleanup = (plspCleanup)GetProcAddres s(Handle, "lspCleanup");
plspParseMsg pParseMsg = (plspParseMsg)GetProcAddre ss(Handle, "lspParseMsg");
if (pInitialize && pCleanup && pParseMsg) {
pInitialize(lspSendMsg);
MessageBox(0, "plugin loaded", "ya", MB_OK);
} else
MessageBox(0, "plugin not loaded", "bah", MB_OK);
}
Plugin Code:
#include <windows.h>
#define Name "dlltest"
// DLL exports
extern "C" _declspec(dllexport) char *__stdcall lspInitialize(void *pSendMsg);
extern "C" _declspec(dllexport) void __stdcall lspCleanup();
extern "C" _declspec(dllexport) void __stdcall lspParseMsg(unsigned short cmd, unsigned short argc, char **args, unsigned long *argl);
char *__stdcall lspInitialize(void *pSendMsg)
{
MessageBox(0, "hi", "", MB_OK);
return Name;
}
void __stdcall lspCleanup()
{
}
void __stdcall lspParseMsg(unsigned short cmd, unsigned short argc, char **args, unsigned long *argl)
{
}
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
break;
}
return TRUE;
}
Client code:
typedef char *(__stdcall *plspInitialize)(void *);
typedef void (__stdcall *plspCleanup)(void);
typedef void (__stdcall *plspParseMsg)(unsigned short, unsigned short, char **, unsigned long *);
HMODULE Handle;
Handle = LoadLibrary("Plugins\\srv_
if (Handle != 0) {
plspInitialize pInitialize = (plspInitialize)GetProcAdd
plspCleanup pCleanup = (plspCleanup)GetProcAddres
plspParseMsg pParseMsg = (plspParseMsg)GetProcAddre
if (pInitialize && pCleanup && pParseMsg) {
pInitialize(lspSendMsg);
MessageBox(0, "plugin loaded", "ya", MB_OK);
} else
MessageBox(0, "plugin not loaded", "bah", MB_OK);
}
Plugin Code:
#include <windows.h>
#define Name "dlltest"
// DLL exports
extern "C" _declspec(dllexport) char *__stdcall lspInitialize(void *pSendMsg);
extern "C" _declspec(dllexport) void __stdcall lspCleanup();
extern "C" _declspec(dllexport) void __stdcall lspParseMsg(unsigned short cmd, unsigned short argc, char **args, unsigned long *argl);
char *__stdcall lspInitialize(void *pSendMsg)
{
MessageBox(0, "hi", "", MB_OK);
return Name;
}
void __stdcall lspCleanup()
{
}
void __stdcall lspParseMsg(unsigned short cmd, unsigned short argc, char **args, unsigned long *argl)
{
}
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
break;
}
return TRUE;
}
ASKER
I need it to be dynamically loaded, not static.. is that what that does?
ASKER
??????????
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
it doesnt matter.. i just wanna know what im doing wrong thats making the pointer pInitialize NULL.. if i know this i'll be able to fix the other 2 if they're "broke"... im doing this for a plugin api so everything needs to be dynamic.. any suggestions?
ASKER
I've tried making the if statement only if (pInitialize) {
still doesnt work..
still doesnt work..
ASKER
Alright I've fixed it using a .DEF file.. now a 2nd problem if you guys want points; how do I pass a pointer to a function inside my exe to a dll? It crashes when i do it right now.. I will increase points if people are actually going to answer this time:
Client code:
typedef void (__stdcall *plspSendMsg)(unsigned short, unsigned short, char **, unsigned long *, unsigned short);
typedef char *(__stdcall *plspInitialize)(void *);
typedef void (__stdcall *plspCleanup)(void);
typedef void (__stdcall *plspParseMsg)(unsigned short, unsigned short, char **, unsigned long *, unsigned short);
void __stdcall lspSendMsg(unsigned short cmd, unsigned short argc, char **args, unsigned long *argl, unsigned short ci)
{
for (unsigned short i = 0; i < ArraySize; i ++) {
if (Clients[i] != NULL) {
if (Clients[i]->ClientIndex == ci) {
Clients[i]->SendMsg(cmd, argc, args,argl);
break;
}
}
}
}
void LoadPlugins()
{
HMODULE Handle;
Handle = LoadLibrary("Plugins\\srv_ capture.dl l");
if (Handle != 0) {
plspInitialize pInitialize = (plspInitialize)GetProcAdd ress(Handl e, "lspInitialize");
plspCleanup pCleanup = (plspCleanup)GetProcAddres s(Handle, "lspCleanup");
plspParseMsg pParseMsg = (plspParseMsg)GetProcAddre ss(Handle, "lspParseMsg");
if (pInitialize && pCleanup && pParseMsg) {
Plugins = (LithiumPlugin **)realloc(Plugins, sizeof(LithiumPlugin));
Plugins[0]->lspInitialize = pInitialize;
Plugins[0]->lspCleanup = pCleanup;
Plugins[0]->lspParseMsg = pParseMsg;
Plugins[0]->Handle = Handle;
Plugins[0]->FileName = "Plugins\\srv_capture.dll" ;
Plugins[0]->Name = pInitialize(lspSendMsg);
}
}
}
Plugin Code:
#include <windows.h>
#include "..\Server\Shared.h"
#define Name "dlltest"
typedef void (__stdcall *plspSendMsg)(unsigned short, unsigned short, char **, unsigned long *, unsigned short);
// DLL exports
extern "C" _declspec(dllexport) char *__stdcall lspInitialize(void *pSendMsg);
extern "C" _declspec(dllexport) void __stdcall lspCleanup();
extern "C" _declspec(dllexport) void __stdcall lspParseMsg(unsigned short cmd, unsigned short argc, char **args, unsigned long *argl, unsigned short ci);
// EXE imports
plspSendMsg lspSendMsg;
char *__stdcall lspInitialize(void *pSendMsg)
{
lspSendMsg = (plspSendMsg)pSendMsg;
return Name;
}
void __stdcall lspCleanup()
{
}
void __stdcall lspParseMsg(unsigned short cmd, unsigned short argc, char **args, unsigned long *argl, unsigned short ci)
{
switch (cmd) {
case 0:
char *Msg = "hi";
unsigned long MsgLn = 2;
lspSendMsg(LCC_CONSOLEMSG, 1, &Msg, &MsgLn, ci);
MessageBox(0, "hi", "hi", MB_OK);
break;
}
}
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
break;
}
return TRUE;
}
Client code:
typedef void (__stdcall *plspSendMsg)(unsigned short, unsigned short, char **, unsigned long *, unsigned short);
typedef char *(__stdcall *plspInitialize)(void *);
typedef void (__stdcall *plspCleanup)(void);
typedef void (__stdcall *plspParseMsg)(unsigned short, unsigned short, char **, unsigned long *, unsigned short);
void __stdcall lspSendMsg(unsigned short cmd, unsigned short argc, char **args, unsigned long *argl, unsigned short ci)
{
for (unsigned short i = 0; i < ArraySize; i ++) {
if (Clients[i] != NULL) {
if (Clients[i]->ClientIndex == ci) {
Clients[i]->SendMsg(cmd, argc, args,argl);
break;
}
}
}
}
void LoadPlugins()
{
HMODULE Handle;
Handle = LoadLibrary("Plugins\\srv_
if (Handle != 0) {
plspInitialize pInitialize = (plspInitialize)GetProcAdd
plspCleanup pCleanup = (plspCleanup)GetProcAddres
plspParseMsg pParseMsg = (plspParseMsg)GetProcAddre
if (pInitialize && pCleanup && pParseMsg) {
Plugins = (LithiumPlugin **)realloc(Plugins, sizeof(LithiumPlugin));
Plugins[0]->lspInitialize = pInitialize;
Plugins[0]->lspCleanup = pCleanup;
Plugins[0]->lspParseMsg = pParseMsg;
Plugins[0]->Handle = Handle;
Plugins[0]->FileName = "Plugins\\srv_capture.dll"
Plugins[0]->Name = pInitialize(lspSendMsg);
}
}
}
Plugin Code:
#include <windows.h>
#include "..\Server\Shared.h"
#define Name "dlltest"
typedef void (__stdcall *plspSendMsg)(unsigned short, unsigned short, char **, unsigned long *, unsigned short);
// DLL exports
extern "C" _declspec(dllexport) char *__stdcall lspInitialize(void *pSendMsg);
extern "C" _declspec(dllexport) void __stdcall lspCleanup();
extern "C" _declspec(dllexport) void __stdcall lspParseMsg(unsigned short cmd, unsigned short argc, char **args, unsigned long *argl, unsigned short ci);
// EXE imports
plspSendMsg lspSendMsg;
char *__stdcall lspInitialize(void *pSendMsg)
{
lspSendMsg = (plspSendMsg)pSendMsg;
return Name;
}
void __stdcall lspCleanup()
{
}
void __stdcall lspParseMsg(unsigned short cmd, unsigned short argc, char **args, unsigned long *argl, unsigned short ci)
{
switch (cmd) {
case 0:
char *Msg = "hi";
unsigned long MsgLn = 2;
lspSendMsg(LCC_CONSOLEMSG,
MessageBox(0, "hi", "hi", MB_OK);
break;
}
}
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
break;
}
return TRUE;
}
Basically You do not suppose to have any problem to pass any kind of pointer since the dll and the exe are running in the same memory space. Can you indicate at what line your program crashes and what message do you get?
--EC--
--EC--
To answer your original question, you might want to take a look at the DLL that you are importing. From the command line, type
DUMPBIN /EXPORTS Plugins\srv_capture.dll
I expect that your variable names have been mangled by the compiler (it changes the names so the linker can determine not only the function name, but also the type information.) To get around this, you can either add the specifier:
extern "C" {
_declspec( dllexport) void myFunction()
{ }
}
to the source of the DLL function (if you have source) which causes the name not to be mangled, or you can fix the parameter that you pass to GetProcAddress so that it looks like the actual function name.
DUMPBIN /EXPORTS Plugins\srv_capture.dll
I expect that your variable names have been mangled by the compiler (it changes the names so the linker can determine not only the function name, but also the type information.) To get around this, you can either add the specifier:
extern "C" {
_declspec( dllexport) void myFunction()
{ }
}
to the source of the DLL function (if you have source) which causes the name not to be mangled, or you can fix the parameter that you pass to GetProcAddress so that it looks like the actual function name.
Run it under the debugger and tell us which on which line the crash appears
ASKER
I dont know, it doesnt tell me.. i start the program in debug and it just exists with this in the console:
The thread 0x610 has exited with code 0 (0x0).
The thread 0x5E4 has exited with code 0 (0x0).
The program 'D:\Lithium\Server\Debug\L ithiumServ er.exe' has exited with code 0 (0x0).
The thread 0x610 has exited with code 0 (0x0).
The thread 0x5E4 has exited with code 0 (0x0).
The program 'D:\Lithium\Server\Debug\L
Maybe it threw an exception that wasn't caught? Add a top level try/catch block.
Maybe it reached an exit point?
Try single-stepping.
Maybe it reached an exit point?
Try single-stepping.
ASKER
The app quits after executing the client line "Plugins[0]->Name = pInitialize(0);" Any ideas?
ASKER
(Does the same with lspSendMsg as a parameter, used 0 for testing.)
ASKER
Hmm.. weird.. the app does not exit in debug mode, but does in release. Wtf?
__declspec(dllimport)char *__stdcall lspInitialize(void *pSendMsg);