vs C++开发lib和dll
vs C++开发lib和dll
lib和dll整体说明的参考链接:https://docs.microsoft.com/zh-cn/windows/win32/dlls/dynamic-link-libraries
dll使用的参考链接:https://blog.csdn.net/qq_29542611/article/details/86618902
lib的创建与使用参考链接:http://www.javashuo.com/article/p-bpliowqg-ox.html
lib的生成和引用参考链接:https://www.likecs.com/show-203435162.html
只生成了dll,而没有生成lib参考链接:https://blog.csdn.net/u012983289/article/details/120525791
vs引入lib的方式:https://docs.microsoft.com/zh-cn/cpp/build/reference/dot-lib-files-as-linker-input?view=msvc-170
vs引入lib的方式2:http://t.zoukankan.com/laohaozi-p-12537588.html
vs lib生成与使用
lib生成
创建lib项目
pch.h
// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
#ifndef PCH_H
#define PCH_H
// 添加要在此处预编译的标头
#include "framework.h"
int add(int a, int b);
int sub(int a, int b);
#endif //PCH_H
pch.cpp
// pch.cpp: 与预编译标头对应的源文件
#include "pch.h"
// 当使用预编译的头时,需要使用此源文件,编译才能成功。
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
create_lib.cpp
// create_lib.cpp : 定义静态库的函数。
//
#include "pch.h"
#include "framework.h"
// TODO: 这是一个库函数示例
void fncreatelib()
{
}
生成
lib使用
需要使用生成的lib和保存了函数声明的头文件pch.h,并且注意删除pch.h中的#include "framework.h"
pch.h
// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
#ifndef PCH_H
#define PCH_H
int add(int a, int b);
int sub(int a, int b);
#endif //PCH_H
use_lib.cpp
// use_lib.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include "pch.h"
#pragma comment(lib,"create_lib.lib")
using namespace std;
int main()
{
int a = 5, b = 2;
cout << add(a, b) << endl;
cout << sub(a, b) << endl;
std::cout << "Hello World!\n";
return 0;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
vs dll生成与使用
dll生成
创建dll项目
pch.h
// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
#ifndef PCH_H
#define PCH_H
// 添加要在此处预编译的标头
#include "framework.h"
void MyDLLProcessAttach(HMODULE hModule);
extern "C" __declspec(dllexport) int __stdcall add(int a, int b);
extern "C" __declspec(dllexport) int __stdcall sub(int a, int b);
#endif //PCH_H
pch.cpp
// pch.cpp: 与预编译标头对应的源文件
#include "pch.h"
__declspec(dllexport) int __stdcall add(int a, int b)
{
return a + b;
}
__declspec(dllexport) int __stdcall sub(int a, int b)
{
return a - b;
}
dllmain.cpp
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <Windows.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <locale.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:MyDLLProcessAttach(hModule); break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
LPCWSTR stringToLPCWSTR(const std::string& s) {
size_t convertedChars = 0;
std::string curLocale = setlocale(LC_ALL, NULL); //curLocale="C"
setlocale(LC_ALL, "chs");
const char* source = s.c_str();
size_t charNum = sizeof(char) * s.size() + 1;
wchar_t* dest = new wchar_t[charNum];
mbstowcs_s(&convertedChars, dest, charNum, source, _TRUNCATE);
setlocale(LC_ALL, curLocale.c_str());
return dest;
}
void MyDLLProcessAttach(HMODULE hModule)
{
char sz[MAX_PATH];
std::string content = "hello MyDLLProcessAttach 中文测试";
::GetModuleFileName(hModule, LPWSTR(sz), MAX_PATH);
::MessageBox(NULL, LPWSTR(stringToLPCWSTR(content)), LPCWSTR(sz), MB_OK);
}
生成dll
可以看到生成的dll和lib,lib是用于在静态加载时使用,即Load-Time动态链接。
也可单独使用dll,即Run-Time动态链接。
下面分别给出两种使用方法的对应代码:
dll使用
Load-Time动态链接
将lib和dll添加到当前项目
右键项目->添加->现有项
load_time_use_dll.cpp
// load_time_use_dll.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
extern "C" int __stdcall add(int a, int b);
extern "C" int __stdcall sub(int a, int b);
#pragma comment(lib,"create_dll.lib")
using namespace std;
int main()
{
int a = 3, b=2;
std::cout << "Hello World!\n";
cout << add(a, b) << endl;
cout << sub(a, b) << endl;
return 0;
}
Run-Time动态链接
仅将dll添加到当前项目
右键项目->添加->现有项
run_time_use_dll.cpp
// run_time_use_dll.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
using namespace std;
LPCWSTR stringToLPCWSTR(const std::string& s) {
size_t convertedChars = 0;
std::string curLocale = setlocale(LC_ALL, NULL); //curLocale="C"
setlocale(LC_ALL, "chs");
const char* source = s.c_str();
size_t charNum = sizeof(char) * s.size() + 1;
wchar_t* dest = new wchar_t[charNum];
mbstowcs_s(&convertedChars, dest, charNum, source, _TRUNCATE);
setlocale(LC_ALL, curLocale.c_str());
return dest;
}
int main()
{
// 运行时加载DLL库
HMODULE module = LoadLibrary(stringToLPCWSTR("create_dll.dll"));
if (module == NULL)
{
printf("加载DLLTest1.dll动态库失败\n");
return 0;
}
int(*add)(int, int) = (int(*)(int, int))GetProcAddress(module, "add");
int(*sub)(int, int) = (int(*)(int, int))GetProcAddress(module, "sub");
int a = 5, b = 2;
cout << add(a, b) << endl;
cout << sub(a, b) << endl;
std::cout << "Hello World!\n";
::FreeLibrary(module);
return 0;
}