动态链接库的编写及使用(c++)

一、编写动态链接库
mydll.cpp:
//dll的入口点
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}
int myadd(int a,int b)
{
    return a+b;
}
int __stdcall mysub(int a,int b)//这里只是为了说明使用__stdcall的情况
{
	return a-b;
}

重要的是怎么导出动态链接库中的函数,首先要知道c/c++的默认的函数调用约定为__cdecl,Win32 API的调用约定是__stdcall(关于__函数的调用约定请自行百度)
1.若函数使用了Win32 API,则函数应使用__stdcall修饰
2.__stdcall会改变函数符号
3.因为c++在导出函数时会改变函数符号,应当用 extern "C"修饰
4.extern "C"和__stdcall不能同时修饰函数(有时候还是会改变函数符号)
5.用.def文件导出函数不会修改函数符号

总结:推荐使用.def导出函数(编译dll的时候就不需要后面两个头文件了),再手动编写两个mydlllib.h和mydll.h分别作为隐式链接和显示链接提供给使用者
mydlllib.h://隐式调用时需要包含的头文件
//这里仅仅是隐式调用dll时的头文件,如果要显示调用,应当再编写一个头文件供外部使用
#pragma once
#pragma comment(lib,"mydll.lib")//这里需要将mydll.lib放到exe文件相同目录
extern "C" __declspec(dllimport) int myadd(int,int); //声明一个可以导出的方法
extern "C" __declspec(dllimport) int __stdcall mysub(int,int); //tt

mydll.h://显式调用时需要包含的头文件
#pragma once
typedef int (* dll_myadd) (int,int);//这里加dll_只是为了在后面定义函数的时候可以取myadd这个变量名
typedef int (__stdcall* dll_mysub) (int,int);


拓展:使用__declspec(dllexport)导出函数的方法
在mydll.cpp添加
#define DLL_API extern "C" __declspec(dllexport)

//mydlllib.h写成:
#pragma once
#ifdef DLL_API
#else
	#pragma comment(lib,"mydll.lib")//这里需要将mydll.lib放到exe文件相同目录
	#define DLL_API extern "C" __declspec(dllimport)
#endif


DLL_API int myadd(int,int); //声明一个可以导出的方法
DLL_API int __stdcall mysub(int,int); //tt

mydll.h不变

二、使用动态链接库
隐式调用:
1.包含mydlllib.h
2.将mydll.lib和mydll.dll复制到exe相同目录


显示调用:
1.包含mydll.h//不包含的话要自己typedef,不嫌麻烦的话也可以
2.将mydll.dll复制到exe相同目录
3.调用时:
HINSTANCE hinstDLL;//获取dll
dll_myadd myadd;//定义函数名
dll_mysub mysub;//定义函数名
hinstDLL = LoadLibrary("sampleDLL.dll");
if (hinstDLL != NULL)
{
    myadd = (dll_myadd) GetProcAddress(hinstDLL, "myadd");//获取函数地址
	mysub = (dll_mysub) GetProcAddress(hinstDLL, "mysub");//获取函数地址
    if (myadd != NULL)
        myadd(1,2);
	if (mysub != NULL)
        mysub(1,2);	
	FreeLibrary(hinstDLL);
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值