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   J·Marcus  阅读(18511)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示