VS2022-动静态库
一、静态库
这里我们先创建两个项目一个是MyLib和一个UsingLib。
我们先把 MyLib属性调成静态库(点击项目的属性)
之后创建一个.cpp文件mylib.cpp,这里我们就用来写一个加法运算吧!
之后我们点击生成。
下面这个图的意思是能够快速找到当前项目的文件路径,并不是库的路径!
经过一番文件的翻阅
我们找到MyLib下的MyLib.lib库---这是我的库路径 D:\Work_Demo\MyLib\x64\Debug
之后我们在UsingLib这个库中的库目录-->添加库的路径,应用确认后编译
在编译的过程中我们发现
D:\Work_Demo\UsingLib\x64\Debug\UsingLib.exe : fatal error LNK1120: 1 个无法解析的外部命令
这里我们无法解析外部命令,我们有两个做法
法一:在main函数上面添加 #pragma comment(lib,"MyLib.lib")
// 法一:
#pragma comment(lib,"MyLib.lib")
int main()
{std::cout << add(1, 2);
}
法二:我们在链接器中输入的附近依赖项添加我们要用到的库MyLib,点击应用。之后编译就通过了。
二、动态库
这里我们先创建两个项目一个是MyDll2和一个USingDll2。我们要在USingDll2中使用MyDll2的函数。
先MyDll2中属性中设置动态库。
然后我们要导出这个函数(MyDll2项目中的mydll.cpp文件中的函数),并进行编译
extern "C" __declspec(dllexport) int add(int a, int b) {return a + b;
}
动态链接有两种方法:
引入一个知识点:
我们发现MyDll2文件中也有个.lib文件,这个.lib文件和我们上次编译静态库大小不同。
因为动态库编译时只包含了相应的符号链接,真正的代码没有包含。静态库编译了所有的东西所以静态库的文件大。
法一:链接静态库 + 动态库
在USingDll2中VC++目录中的库目录添加MyDll2中.lib文件的路径
然后再把MyDll2.dll拷贝到此目录下
并链接MyDll2.dll库
之后我们之间在USingDll2项目的main函数中运行即可。
extern "C" __declspec(dllimport) int add(int a, int b);int main()
{std::cout << add(1, 2);
}
以上的做法大部分都是这么下的如下:
MyDll2项目:
USingDll2项目中
法二: 直接使用动态库
我们在之前把VC++目录中的库目录和链接中的内容都删除掉。然后把MyDll2.dll拷贝到法一所说的路径中。之后运行就成功了
#include <iostream>
#include <Windows.h>
int main()
{// 把动态库加载到内存// 在 Windows 编程体系中,HINSTANCE 是一种句柄类型。// 句柄的作用类似于指针,不过它更为 “抽象”,主要用于标识某个对象。// HINSTANCE 专门用来标识加载到内存中的模块,// 这里的模块既可以是 DLL(动态链接库),也可以是 EXE(可执行文件)。HINSTANCE hDll = LoadLibrary(L"MyDll2.dll");// 加载失败if (hDll == NULL) {std::cout << "Load dll failed";return -1;}// 函数指针using functionPtr = int(*)(int, int);// 从已加载的 DLL(由 hDll 句柄标识)中查找名为 add 的导出函数,并返回其内存地址。// 若找到函数,返回函数的内存地址(FARPROC 类型,本质是 void*),需强制转换为 functionPtr 类型。// 若未找到(如函数名拼写错误、函数未正确导出),返回 NULL。functionPtr addFunction = (functionPtr)GetProcAddress(hDll, "add");if (addFunction == NULL) {std::cout << "cannot find target function!";return -1;}std::cout << addFunction(1, 2);
}
三、例子
接下来我要写一个Demo级别的小例子,用到的是动态链接,上面动态链接没看懂的,可以看下面,这次我写个超级详细的!
首先创建一个Demo项目,和一个UsingDemo项目
Demo项目中,我们创建了demo.h和demo.cpp
demo.h
#pragma once// 关键:通过BHDLL_EXPORTS宏区分导出/导入
#ifndef DEMO_EXPORTS
#define DEMO __declspec(dllexport) // 生成DLL时使用导出
#else
#define DEMO __declspec(dllimport) // 调用DLL时使用导入
#endif//编写代码区域//导出函数DEMO int add(int a, int b);
DEMO int sub(int a, int b);//导出类class DEMO dllH
{
public:int mul(int a, int b);int div(int a, int b);
};//以C语言方式导出函数:
extern "C"
{DEMO int Cadd(int a, int b);DEMO int Csub(int a, int b);
}
demo.cpp
#define _CRT_SECURE_NO_WARNINGS 1#include "demo.h"
#include <iostream>using namespace std;DEMO int add(int a, int b)
{return a + b;
}
DEMO int sub(int a, int b)
{return a - b;
}DEMO int dllH::mul(int a, int b)
{return a * b;
}
DEMO int dllH::div(int a, int b)
{return a / b;
}DEMO int Cadd(int a, int b)
{return a + b;
}
DEMO int Csub(int a, int b)
{return a - b;
}
注意!!!!我这里是Debug X64
点击应用,并生成解决方案,之后我们要找到Demo.dll,Demo.lib这个位置。
我们创建好UsingDemo项目后在他路径下,创建两个文件夹一个是include用来头文件,一个lib是用来放库。
之后我们把Demo项目中的头文件放到include中,然后把Demo.lib放到lib中,把Demo.dll放到与include和lib同路径下。
之后进入UsingDemo这个项目中把include的绝对路径写到包含目录里,把lib的绝对路径写到库目录里。
链接器输入中添加Demo.lib库
点击应用后,写个main函数开始用这个库吧
#include <iostream>
#include <Demo.h>#define DEMO_EXPORTS
using namespace std;
int main()
{cout << add(1, 0) << endl;cout << sub(1, 0) << endl;dllH DH;cout << DH.div(4, 2) << endl;cout << DH.mul(4, 2) << endl;cout << Cadd(1, 0) << endl;cout << Csub(1, 0) << endl;return 0;
}
如果对你有帮助的话,帮忙 点赞+收藏 支持一下博主,谢谢。