2013-03-18 53 views
1

我创建了一个DLL文件(helloWorld.dll):调用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; 
} 

之后,我创建了一个CPP,我想调用(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; 
} 

如何调用Hello()函数?

+0

请参阅['GetProcAddress()'](http://msdn.microsoft.com/en-gb/library/windows/desktop/ms683212%28v=vs.85%29.aspx)参考页,有一个例如它。 – hmjd 2013-03-18 17:15:54

+1

使用LoadLibrary是困难的方式 - 如果您不知道该DLL是否存在(或者可能称为),则可以使用LoadLibrary。如果你没有这些特殊需求,有一种简单的方法可以让编译器/链接器为你做所有的工作。 – Elemental 2013-03-18 17:21:00

+0

“HWND_DESKTOP”的用途是什么? – 2013-03-18 17:25:17

回答

5

在问题中的代码包含了一些错误:

  1. LoadLibrary回报HMODULE和不是HINSTANCE
  2. 函数指针具有错误的返回值和不正确的调用约定。
  3. 函数名称区分大小写,您必须考虑名称装饰。
  4. 你根本没有检查错误。您的代码可能在拨打GetProcAddress时失败,返回NULL,然后在尝试调用NULL处的函数时发生炸弹。

所以,你需要的东西是这样的:

typedef int (__stdcall *HelloProc)(); 
.... 
HMODULE hdll = LoadLibrary("HelloWorld.dll"); 
if (hdll == NULL) 
    // handle error 
HelloProc Hello = (HelloProc)GetProcAddress(hdll, "[email protected]"); 
if (Hello == NULL) 
    // handle error 
int retval = Hello(); 

函数名饰,因为你使用__stdcall。如果您使用过__cdecl或.def文件,那么就没有装饰。我假设MSVC装饰。看起来装饰与编译器mingw不同,函数名为"[email protected]"

坦率地说,使用.lib文件而不是调用LoadLibraryGetProcAddress要容易得多。如果可以的话,我现在可以切换到这种方式。

+0

使用'extern“C'''__stdcall'不会装饰导出的名称。正如预期的那样,正确的导出名称将是'“Hello”。 – 2013-03-18 17:32:08

+0

感谢您的回复,我修改了我的代码,请参阅 – David 2013-03-18 17:34:53

+0

您需要修饰名称。该函数被导出为“_Hello @ 0”。再看看我的答案。 – 2013-03-18 17:36:04