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;
}
文章目录