views:

50

answers:

4

I'm trying to load a DLL dynamically using LoadLibrary(), which works, however I cannot then get the address of the function in the DLL that I'm trying to call.

DLL function: (in CPP file)

_declspec(dllexport) void MyDllFunc()
{
    printf("Hello from DLL");
}

Calling code:

typedef void (*MyDllFuncPtr)();

int _tmain(int argc, _TCHAR* argv[])
{

    HINSTANCE LoadMe;
    LPCWSTR str = L"C:\\Users\\Tony\\Documents\\Visual Studio 2008\\Projects\\DLL Loading\\Release\\MyDll.dll";

    LoadMe = LoadLibrary(str);

    if(LoadMe != 0)
        printf("Successfully Loaded!\r\n");
    else
        printf("Loading Failed \r\n" );


    MyDllFuncPtr func;

    func = (MyDllFuncPtr)GetProcAddress(LoadMe, "MyDllFunc");

    if (func != NULL)
        func();

    FreeLibrary(LoadMe);

}

func returns NULL!!!

What am I doing wrong?

This is a Win32 Console project.

+3  A: 

Write

extern "C" _declspec(dllexport) void MyDllFunc()
Artyom
in DLL or in calling code??
Tony
In DLL is enough. So the name would be mangled correctly and you'll be able to get the symbol.
Artyom
A: 

If the DLL is built as a C++ dll, it's functions' names will change. This is compiler dependent. I'd strongly recommend to make it a C dll (C interface + C++ guts). I don't have an example on me right now, but you should be able to find something on the net.

Maciek
+1  A: 

You're doing it wrong. __declspec(dllexport) pairs with __declspec(dllimport).

#1: In the DLL, declare the function's prototype with __declspec(dllexport).
#2: In the .exe, declare the function's prototype with __declspec(dllimport).
#3: Compile the .dll. You should also get a .lib file.
#4: Link the .exe with the .lib, and compile.
#5: Success.

When you use __declspec(dllimport) and __declspec(dllexport), you never need to touch the WinAPI functions for loading a DLL. dllimport/export does it all for you. In addition, you don't need to extern C anything.

DeadMG
+1  A: 

Your exported functions name's are being decorated when using __declspec(dllexport), you can reduce the decoration using extern "C", however, it will not fully undecorated the symbol, to do that you need to use a def file and export it as a named symbol, else you need to use GetProcAddress using the mangled/decorated symbol name, which is short when exported using extern "C".

Necrolis
Great point, people tend to forget that many C compilers decorate names too.
bk1e