静态连接库在编译的时候 会将库函数编译到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
版权声明:本文为qq_34479012原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。