LoadLibrary方法加载运行DLL库

最近和另一家公司对接,要求用对方提供的测试程序测试我们做的DLL。

接到对方的测试程序,发现和我们以前调用DLL的方式不太一样。但我稍微看了一会代码也看懂其意思了,一天搞定了。

但其中也遇到些小困惑,记录一下。

 

下面是我实验写的小Demo

my_dll.h:

#ifdef MY_DLL_EXPORTS
#define MY_DLL_API __declspec(dllexport)
#else
#define MY_DLL_API __declspec(dllimport)
#endif


extern "C" MY_DLL_API int WINAPI fnmy_dll(void);

my_dll.cpp:

#include "stdafx.h"
#include "my_dll.h"

extern "C"
{
// 这是导出函数的一个示例。
    MY_DLL_API int WINAPI fnmy_dll(void)
    {
        MessageBox(NULL,L"ddd",L"xxx",NULL);
        return 42;
    }
}

test_dll.cpp:

#include "stdafx.h"

typedef int (WINAPI *MY_FUNC)(void);
MY_FUNC func;


int _tmain(int argc, _TCHAR* argv[]) 
{
    HMODULE  g_hDll = LoadLibrary(L"my_dll.dll");
    if (g_hDll)    
        func = (MY_FUNC)GetProcAddress(g_hDll, "fnmy_dll");
    func();
    return 0;
}

两个工程(一个dll,一个调用dll的测试工程)的结构:

LoadLibrary是加载dll库文件GetProcAddress函数则是找到函数地址,这里要声明函数指针,指向找到的函数地址,之后通过函数指针使用函数。

值得注意的一点是dll文件里,dll工程导出函数要加 extern "C"。这样导出的函数是C语言方式的名称,否则就是C++方式的名称。如果是后者,使用dll时候,用函数原名会找不到。

 

 WINAPI标识的是函数调用的方式。dll里导出函数声明为WINAPI则调用DLL的工程声明的函数指针也要声明WINAPI。

网友给出回答:
在windef.h头文件中有如下定义
#define WINAPI      __stdcall
#define APIENTRY    WINAPI
VC有两种函数调用方式 一种是__stdcall,另一种是__cdecl
函数的调用方式有两种一种是PASCAL调用方式,另一种是C调用方式
使用PASCAL调用方式,函数在返回到调用者之前将参数从栈中删除
使用C调用方式,参数的删除是调用者完成的
WinMain函数是由系统调用的,Windows系统规定由系统调用的函数都遵守PASCAL调用方式
但是VC中函数的缺省调用方式是__cdecl,也就是C调用方式
所以在WinMain前显示的声明。
在Windows编程中将遇到很多声明修饰符,如CALLBACK,WINAPI,PASCAL这些在IntelCPU的计算机上都是__stdcall
详细的声明细节请看windef.h文件

posted on 2018-04-26 20:21  J·Marcus  阅读(15155)  评论(0编辑  收藏  举报

导航