Link to home
Start Free TrialLog in
Avatar of Olympus
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.dll");

     if (Handle != 0) {
          plspInitialize pInitialize = (plspInitialize)GetProcAddress(Handle, "lspInitialize");
          plspCleanup pCleanup = (plspCleanup)GetProcAddress(Handle, "lspCleanup");
          plspParseMsg pParseMsg = (plspParseMsg)GetProcAddress(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;
}
Avatar of nsrvijay
nsrvijay

did u try importing it this way:
__declspec(dllimport)char *__stdcall lspInitialize(void *pSendMsg);
Avatar of Olympus

ASKER

I need it to be dynamically loaded, not static.. is that what that does?
Avatar of Olympus

ASKER

??????????
ASKER CERTIFIED SOLUTION
Avatar of elcapitan
elcapitan

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Olympus

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?
Avatar of Olympus

ASKER

I've tried making the if statement only if (pInitialize) {

still doesnt work..
Avatar of Olympus

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.dll");

     if (Handle != 0) {
          plspInitialize pInitialize = (plspInitialize)GetProcAddress(Handle, "lspInitialize");
          plspCleanup pCleanup = (plspCleanup)GetProcAddress(Handle, "lspCleanup");
          plspParseMsg pParseMsg = (plspParseMsg)GetProcAddress(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;
}
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--
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.
Run it under the debugger and tell us which on which line the crash appears
Avatar of Olympus

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\LithiumServer.exe' has exited with code 0 (0x0).
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.
Avatar of Olympus

ASKER

The app quits after executing the client line "Plugins[0]->Name = pInitialize(0);"  Any ideas?
Avatar of Olympus

ASKER

(Does the same with lspSendMsg as a parameter, used 0 for testing.)
Avatar of Olympus

ASKER

Hmm.. weird.. the app does not exit in debug mode, but does in release.  Wtf?