调用动态连接库

  • Post author:
  • Post category:其他


静态连接库在编译的时候 会将库函数编译到exe文件中,而动态链接库在编译时 不会编译到exe中,每个动态链接库dll都是独立的,使用动态链接库后期可以分模块(dll)编译  无需所有工程代码全部编译,比较灵活

编译生成一个动态连接库(未隐藏函数名)

// MyDll.h: interface for the MyDll class.
//
//

#if !defined(AFX_MYDLL_H__6532EDCD_DCC5_418A_A082_3BA89A9BC522__INCLUDED_)
#define AFX_MYDLL_H__6532EDCD_DCC5_418A_A082_3BA89A9BC522__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

//extern 标志全局函数
//"C"  C语言形式 防止函数重载 函数名变为乱码
//_declspec(dllexport)  导出函数
//__stdcall 内平栈


extern "C" __declspec(dllexport) __stdcall int Pls(int x,int y);
extern "C" __declspec(dllexport) __stdcall int Sub(int x,int y);
extern "C" __declspec(dllexport) __stdcall int Mul(int x,int y);
extern "C" __declspec(dllexport) __stdcall int Div(int x,int y);

#endif // !defined(AFX_MYDLL_H__6532EDCD_DCC5_418A_A082_3BA89A9BC522__INCLUDED_)
// MyDll.cpp: implementation of the MyDll class.
//
//

#include "stdafx.h"
#include "MyDll.h"

//
// Construction/Destruction
//

int __stdcall Pls(int x,int y){ return x+y; }
int __stdcall Sub(int x,int y){ return x-y; }
int __stdcall Mul(int x,int y){ return x*y; }
int __stdcall Div(int x,int y){ return x/y; }

隐式调用动态链接库

#include <stdio.h>
#pragma comment(lib,"TestDll.lib")

extern "C" __declspec(dllimport)  __stdcall  Pls(int x,int y);
extern "C" __declspec(dllimport)  __stdcall  Sub(int x,int y);
extern "C" __declspec(dllimport)  __stdcall  Mul(int x,int y);
extern "C" __declspec(dllimport)  __stdcall  Div(int x,int y);

int main(int argc,char* argv[])
{
	int x=Pls(1,2);
	printf("%d \n",x);
	getchar();
	return 0;
}

需要把dll和lib放到 exe目录 不然可能找不到动态库

可以看到dll模块已经加载进去了

显式调用动态链接库

#include <stdio.h>
#include <Windows.h>
#pragma comment(lib,"TestDll.lib")

//声明函数指针
typedef int (__stdcall *lpPls)(int,int);
typedef int (__stdcall *lpSub)(int,int);
typedef int (__stdcall *lpMul)(int,int);
typedef int (__stdcall *lpDiv)(int,int);

int main(int argc,char* argv[])
{
	lpPls myPlus;
	lpSub mySub;
	lpMul myMul;
	lpDiv myDiv;
	//加载dll到内存
	HINSTANCE hModule = LoadLibrary("TestDll.dll");

	myPlus=(lpPls)GetProcAddress(hModule,"_Pls@8");  // 这个名字是从depends里面查到的

	int x=myPlus(1,2);
	printf("%d \n",x);
	getchar();
	return 0;
}

编译生成一个动态连接库(隐藏函数名)

修改导出方式 去掉export

// MyDll.h: interface for the MyDll class.
//
//

#if !defined(AFX_MYDLL_H__6532EDCD_DCC5_418A_A082_3BA89A9BC522__INCLUDED_)
#define AFX_MYDLL_H__6532EDCD_DCC5_418A_A082_3BA89A9BC522__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

__stdcall int Pls(int x,int y);
__stdcall int Sub(int x,int y);
__stdcall int Mul(int x,int y);
__stdcall int Div(int x,int y);

#endif // !defined(AFX_MYDLL_H__6532EDCD_DCC5_418A_A082_3BA89A9BC522__INCLUDED_)

新增一个def文件 隐藏名字属性

EXPORTS

Pls @12
Sub @15 NONAME
Mul @13
Div @16

再次用depends查看 sub的函数名已经被隐藏了

注意 这里的函数名已经变了 ,使用时 以depends里面的函数名为准,上面那段代码 函数名载入时需要修改一下

myPlus=(lpPls)GetProcAddress(hModule,"Pls");

运行结果

PS:depends这个工具好像已经不支持win10了 可以从官网下载然后用win7虚拟机跑 我上面是在xp上运行的 包括VC6


Dependency Walker (depends.exe) Home Page



版权声明:本文为qq_34479012原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。