1

I created a DLL file (helloWorld.dll):

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#define DLL_FUNC extern "C" __declspec(dllexport)

DLL_FUNC int __stdcall Hello() {
    MessageBox(HWND_DESKTOP, "Hello, world", "MEssage", MB_OK);
    return 0;
 }

After that I created a cpp where I would like to call (useDLL.cpp)

#include <windows.h>
#include <stdio.h>

int main () {
    typedef void (*pfunc)();
    HINSTANCE hdll = LoadLibrary("HelloWorld.dll");
    pfunc Hello;
    Hello = (pfunc)GetProcAddress(hdll, "hello");
    Hello();
    return 0;
}

How can I call the Hello() function?

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
szuniverse
  • 1,076
  • 4
  • 17
  • 32
  • See [`GetProcAddress()`](http://msdn.microsoft.com/en-gb/library/windows/desktop/ms683212%28v=vs.85%29.aspx) reference page, there is an example on it. – hmjd Mar 18 '13 at 17:15
  • 1
    Using LoadLibrary is the hard way - to be used if you don't know whether the DLL will be present (or perhaps what it is called). There is an easy way to get the compiler/linker to do it all for you if you don't have these special needs. – Elemental Mar 18 '13 at 17:21
  • What's that use of `HWND_DESKTOP` all about? – David Heffernan Mar 18 '13 at 17:25
  • When asking a question like this, you should explain how your program fails. I think you are experiencing a seg fault. But it would be better if you said so in the question. – David Heffernan Mar 18 '13 at 17:31
  • I rolled the question back to its original form. If you want to add more information, add it, but don't remove the original question. Otherwise it looks a bit daft that my answer contains code that is identical to your question. – David Heffernan Mar 18 '13 at 17:45

2 Answers2

5

The code in the question contains a number of errors:

  1. LoadLibrary returns HMODULE and not HINSTANCE
  2. The function pointer has the wrong return value and an incorrect calling convention.
  3. Function names are case sensitive and you must account for name decoration.
  4. You did no error checking at all. Your code probably fails on the call to GetProcAddress, returns NULL and then bombs when you try to call the function at NULL.

So you need something like this:

typedef int (__stdcall *HelloProc)();
....
HMODULE hdll = LoadLibrary("HelloWorld.dll");
if (hdll == NULL)
    // handle error
HelloProc Hello = (HelloProc)GetProcAddress(hdll, "_Hello@0");
if (Hello == NULL)
    // handle error
int retval = Hello();

The function name is decorated because you used __stdcall. If you had used __cdecl, or a .def file, then there would have been no decoration. I'm assuming MSVC decoration. It seems that decoration differs with your compiler, mingw, and the function is named "Hello@0".

Frankly it's much easier to do it with a .lib file instead of calling LoadLibrary and GetProcAddress. If you can, I'd switch to that way now.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Using `extern "C"` with `__stdcall` WILL NOT decorate the exported name. The correct exported name will be `"Hello"` as expected. – Remy Lebeau Mar 18 '13 at 17:32
  • You need to decorate the name. The function is exported as `"_Hello@0"`. Look again at my answer. – David Heffernan Mar 18 '13 at 17:36
  • @Remy No, it is exactly as I stated. The documentation is here: http://msdn.microsoft.com/en-us/library/zxk0tw93(v=vs.110).aspx – David Heffernan Mar 18 '13 at 17:38
  • I modified but I got the same message: Hello is NULL. I updated my code. – szuniverse Mar 18 '13 at 17:38
  • I just compiled the code from your latest update. And I see the message "Hello World". Keep trying. – David Heffernan Mar 18 '13 at 17:42
  • Is it possible when I compile the DLL file I doing something wrong? I use mingW with this options: g++ -Wall -shared HelloWorld.cpp -o c:\Helloworld.dll – szuniverse Mar 18 '13 at 17:49
  • OK, mingw appears to use different decoration. I assumed Visual Studio. I think the decoration from mingw is `"Hello@0"`. I think that should do it!! – David Heffernan Mar 18 '13 at 17:51
  • Yes I found the same here: http://www.willus.com/mingw/yongweiwu_stdcall.html but the message still "Hello is NULL" – szuniverse Mar 18 '13 at 18:01
  • Well, I compiled with g++ and it worked well for me. I'm using tools to find out the exported name. Specifically MS Dependency Walker. What's more I don't actually know the precise compiler version that you are using. You didn't say. Is it 32 or 64 bit? Anyway, use a tool like Dependency Walker to find out how your function is exported. The answer is correct. You just need to do the final debugging of your local environment. – David Heffernan Mar 18 '13 at 18:05
  • Er, that's what I said!! Glad you got there in the end. Top tip is to use a tool to check how your functions are exported. Dependency Walker does that very well. – David Heffernan Mar 18 '13 at 18:08
  • I've got another question. I would like to get a string from the dll. Could you send me something useful? – szuniverse Mar 18 '13 at 18:44
  • @David please ask a new question. Mind you it will be a duplicate. That's been asked hundreds of times. – David Heffernan Mar 18 '13 at 18:50
  • @DavidHeffernan: Fine, whatever – Remy Lebeau Mar 18 '13 at 23:23
0

You need to specifically search and find specific functions you are lookins for, check out this link: Calling functions in a DLL from C++

Community
  • 1
  • 1
Alon
  • 1,776
  • 13
  • 31