C语言动静态链接库使用(笔记)
看了视频一直没空写...........
C静态链接库不用说了跟你写在cpp文件里的函数一样不会有单独的模块 不再赘述生活中用的比较少
例子
.h文件
int Plus(int x, int y); int Sub(int x, int y); int Mul(int x, int y); int Div(int x, int y);
cpp
int Plus(int x, int y) { return x+y; } int Sub(int x, int y) { return x-y; } int Mul(int x, int y) { return x*y; } int Div(int x, int y) { return x/y; }
使用方法 编译出来的lib文件和.h文件和你需要用lib的项目放在同一文件夹下
点击项目属性 library modules把你的lib添加到后面
C 动态链接库
2、头文件中 extern "C" _declspec(dllexport) __stdcall int Plus (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);
cpp
int __stdcall Plus(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; }
vs 可能要把int 放在 _declspec前面
__stdcall意思是内平栈 再函数返回时就平衡堆栈
DLL的使用
方式一:隐式连接 步骤1:将 *.dll *.lib 放到工程目录下面 步骤2:将 #pragma comment(lib,"DLL名.lib") 添加到调用文件中 步骤3:加入函数的声明 extern "C" __declspec(dllimport) __stdcall int Plus (int x,int y); extern "C" __declspec(dllimport) __stdcall int Sub (int x,int y); extern "C" __declspec(dllimport) __stdcall int Mul (int x,int y); extern "C" __declspec(dllimport) __stdcall int Div (int x,int y); 说明: 加extern c 以 c的形式编译 __declspec(dllimport)告诉编译器此函数为导入函数;
方式二
方式二:显示链接 步骤1: //定义函数指针 typedef int (__stdcall *lpPlus)(int,int); typedef int (__stdcall *lpSub)(int,int); typedef int (__stdcall *lpMul)(int,int); typedef int (__stdcall *lpDiv)(int,int); 步骤2: //声明函数指针变量 lpPlus myPlus; lpSub mySub; lpMul myMul; lpDiv myDiv; 步骤3: // //动态加载dll到内存中 HINSTANCE hModule = LoadLibrary("DllDemo.dll"); 步骤4: //获取函数地址 myPlus = (lpPlus)GetProcAddress(hModule, "_Plus@8"); mySub = (lpSub)GetProcAddress(hModule, "_Sub@8"); myMul = (lpMul)GetProcAddress(hModule, "_Mul@8"); myDiv = (lpDiv)GetProcAddress(hModule, "_Div@8"); 步骤5: //调用函数 int a = myPlus(10,2); int b = mySub(10,2); int c = myMul(10,2); int d = myDiv(10,2);
提示具体函数生成什么名字可以用dll函数查看器看一下 这种方式生成的会更改函数名称的
def 导出函数 和函数名称一样 也可以把dll 导出名称定义成匿名的防止别人调用
头文件和CPP文件定义和你平时写的一样就行了
1、*.h文件 int Plus (int x,int y); int Sub (int x,int y); int Mul (int x,int y); int Div (int x,int y); 2、*.cpp文件 int Plus(int x,int y) { return x+y; } int Sub(int x,int y) { return x-y; } int Mul(int x,int y) { return x*y; } int Div(int x,int y) { return x/y; }
3、*.def文件 EXPORTS Plus @12 Sub @15 NONAME Mul @13 Div @16
其中NONAME 不显示调用函数名 使用序号调用 关于文件怎么定义和配置可以参考一下 https://blog.csdn.net/hanxiucaolss/article/details/95079199
def匿名dll函数调用方法(和上面的类似只不过这个是序号调用)
#include "stdafx.h" typedef int( *lpPlus)(int, int); typedef int( *lpSub)(int, int); typedef int( *lpMul)(int, int); typedef int( *lpDiv)(int, int); int _tmain(int argc, _TCHAR* argv[]) { lpPlus myPlus; lpSub mySub; lpMul myMul; lpDiv myDiv; HINSTANCE hModule = LoadLibrary(L"windll.dll"); /* Handle 是代表系统的内核对象,如文件句柄,线程句柄,进程句柄。 HMODULE 是代表应用程序载入的模块 HINSTANCE 在win32下与HMODULE是相同的东西 Win16 遗留 HWND 是窗口句柄 其实就是一个无符号整型,Windows之所以这样设计有2个目的: 1、可读性更好 2、避免在无意中进行运算 */ myPlus = (lpPlus)GetProcAddress(hModule, (char*)12);//这里的12是你原来定义的序号//mySub = (lpSub)GetProcAddress(hModule, "_Sub@8"); //myMul = (lpMul)GetProcAddress(hModule, "_Mul@8"); //myDiv = (lpDiv)GetProcAddress(hModule, "_Div@8"); //printf_s("%x", GetProcAddress(hModule, "Plus")); printf_s("%d", myPlus(1, 2)); return 0; }