visual studio 创建和使用自己的动态库dll

一,什么是DLL

        DLL 是一个包含可由多个程序同时使用的代码和数据的库。对于 Windows 操作系统,操作系统的大部分功能都由 DLL 提供。 另外,当您在这些 Windows 操作系统之一上运行某一程序时,该程序的很多功能可能是由 DLL 提供的。 例如,某些程序可能包含很多不同的模块,而该程序的每个模块都包含在 DLL 中并从中分发。使用 DLL 有助于促进代码的模块化、代码重用、内存的有效使用和减少所占用的磁盘空间。 因此,操作系统和程序能够更快地加载和运行,并且在计算机中占用较少的磁盘空间。当程序使用 DLL 时,一个称为依赖性的问题可能导致该程序无法运行。 当程序使用 DLL 时,就会创建一个依赖项。 如果其他程序改写和损坏了该依赖项,原来的那个程序就可能无法成功运行。

二,DLL优点是什么

        1,使用较少的资源;2,推广模块式体系结构,有助于模块式程序的开发;3,简化部署与安装,当DLL需要更新与修复时,部署和安装DLL不需要重新建立程序与该DLL的链接。

三,DLL的类型

        DLL的类型:在应用程序中加载 DLL 时,可以使用两种链接方法来调用导出的 DLL 函数。 这两种链接方法是加载时动态链接和运行时动态链接

四、导出DLL函数

        要导出 DLL 函数,您可以向导出的 DLL 函数中添加函数关键字,也可以创建模块定义文件 (.def) 以列出导出的 DLL 函数。要使用函数关键字,您必须使用以下关键字来声明要导出的各个函数:
__declspec(dllexport)若要在应用程序中使用导出的 DLL 函数,必须使用以下关键字 (keyword) 声明要导入的每个函数:__declspec(dllimport)通常情况下,会使用一个包含 define 语句和 ifdef 语句的头文件,以便分隔导出语句和 import 语句。

五、创建自己的DLL和调用DLL流程

        流程:首先使用visual studio 2022创建自己的dll-将函数与变量导入到dll---使用visual studio 2022创建控制台项目-将DLL标头包含到库目录-将DLL库添加到项目(包含了输入.lib和常规中附加库目录,指的是.lib相应的路径)

        5.1.首先创建自己的动态库项目,选择c++->Windows平台->库->动态链接库(DLL),然后创建项目。在创建项目名称MathLibrary,解决方案名称为-MyDailyStudy.

然后为函数创建头文件MathLibrary.h和对应的MathLibrary.cpp文件。具体操作方式为:菜单栏上选择“项目”>“添加新项”。在“添加新项”对话框的左窗格中,选择“Visual C++”。 在中间窗格中,选择 “头文件(.h)”。 指定 MathLibrary.h 作为头文件的名称。

       在创建完成后,在源文件中会自动生成一个dllmain.cpp文件,该文件包含了DLL的入口函数。

        在创建的MathLibrary.h头文件首先输入预处理指令和相应的函数声明。下边代码给出了Microsoft示例代码。

        头文件顶部的预处理器语句的作用是 DLL 项目的新项目模板会将 <PROJECTNAME>_EXPORTS 添加到定义预处理器宏。 在此示例中,Visual Studio 在生成 MathLibrary DLL 项目时定义 MATHLIBRARY_EXPORTS。定义 MATHLIBRARY_EXPORTS 宏时,MATHLIBRARY_API 宏会对函数声明设置 __declspec(dllexport) 修饰符。__declspec(dllexport) 修饰符 指示编译器和链接器从 DLL 导出函数或变量,以便其他应用程序可以使用它。

如果未定义 MATHLIBRARY_EXPORTS(例如,当客户端应用程序包含头文件时),

MATHLIBRARY_API 会将 __declspec(dllimport) 修饰符应用于声明,此修饰符可优化应用程序中函数或变量的导入。 

// MathLibrary.h - Contains declarations of math functions
#pragma once

#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)   //_declspec(dllexport)关键字用于声明要导出的各个函数;
#else
#define MATHLIBRARY_API __declspec(dllimport)   //若要在应用程序中使用导出的 DLL 函数,必须使用以下关键字 (keyword) 声明要导入的每个函数:__declspec(dllimport)
#endif

// The Fibonacci recurrence relation describes a sequence F
// where F(n) is { n = 0, a
//               { n = 1, b
//               { n > 1, F(n-2) + F(n-1)
// for some initial integral values a and b.
// If the sequence is initialized F(0) = 1, F(1) = 1,
// then this relation produces the well-known Fibonacci
// sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

// Initialize a Fibonacci relation sequence
// such that F(0) = a, F(1) = b.
// This function must be called before any other function.
extern "C" MATHLIBRARY_API void fibonacci_init(
    const unsigned long long a, const unsigned long long b);

// Produce the next value in the sequence.
// Returns true on success and updates current value and index;
// false on overflow, leaves current value and index unchanged.
extern "C" MATHLIBRARY_API bool fibonacci_next();

// Get the current value in the sequence.
extern "C" MATHLIBRARY_API unsigned long long fibonacci_current();

// Get the position of the current value in the sequence.
extern "C" MATHLIBRARY_API unsigned fibonacci_index();

//*********************最小二乘法线线性拟合*****************************
extern "C" MATHLIBRARY_API void Least_Squares_1(float x[], float y[], float n, float& k, float& b);
extern "C" MATHLIBRARY_API void Least_Squares_2(float x[], float y[], float n, float& a, float& b, float& c);


        然后在MathLibrary.cpp中定义头文件中声明的各种函数。具体代码如下:

// MathLibrary.cpp : Defines the exported functions for the DLL.
#include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier
#include <utility>
#include <limits.h>
#include "MathLibrary.h"

// DLL internal state variables:
static unsigned long long previous_;  // Previous value, if any
static unsigned long long current_;   // Current sequence value
static unsigned index_;               // Current seq. position

// Initialize a Fibonacci relation sequence
// such that F(0) = a, F(1) = b.
// This function must be called before any other function.
void fibonacci_init(
    const unsigned long long a,
    const unsigned long long b)
{
    index_ = 0;
    current_ = a;
    previous_ = b; // see special case when initialized
}

// Produce the next value in the sequence.
// Returns true on success, false on overflow.
bool fibonacci_next()
{
    // check to see if we'd overflow result or position
    if ((ULLONG_MAX - previous_ < current_) ||
        (UINT_MAX == index_))
    {
        return false;
    }

    // Special case when index == 0, just return b value
    if (index_ > 0)
    {
        // otherwise, calculate next sequence value
        previous_ += current_;
    }
    std::swap(current_, previous_);
    ++index_;
    return true;
}

// Get the current value in the sequence.
unsigned long long fibonacci_current()
{
    return current_;
}

// Get the current index position in the sequence.
unsigned fibonacci_index()
{
    return index_;
}

以上两个文件全部创建完毕,点击生成-生成解决方案,编译结果如下。在解决方案MyDailyStudy目录下的Debug文件夹中生成4个文件。

        5.2.创建控制台项目,将上述生成的dll添加到控制台项目中使用。创建控制台项目的方法可以是直接在解决方案MyDailyStudy下添加新项目。创建的控制应用TestDLL项目如果想使用MathLibrary.cpp中的函数,必须将MathLibrary.h添加进来,同时还需要链接到MathLibrary.dll文件。具体的dll使用方法:首先将dll 标头(MathLibrary.h)添加到包含路径,这是就可以在自己创建爱你的控制台项目TestDLL.cpp中将MathLibrary.h的头文件包含进来;然后DLL库添加到控制台项目,具体操作方法是配置属性->链接器->输入中的附加以来项中添加MathLibrary.lib。然后将MathLibrary.lib的路径添加到链接器->常规中的附加库目录中。此时就可以进行编译和生成解决方案了。

参考文档:演练:创建和使用自己的动态链接库 (C++) | Microsoft Learn

  • 20
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Visual Studio 2022 中,使用动态库的步骤如下: 1. 创建一个新的项目或打开现有项目。 2. 在“解决方案资源管理器”中,右键单击你的项目并选择“属性”。 3. 在属性窗口中,选择“VC++ 目录”选项卡。 4. 在“包含目录”中添加动态库头文件的路径。 5. 在“库目录”中添加动态库文件的路径。 6. 在“链接器”选项卡中,选择“输入”子选项卡。 7. 在“附加依赖项”中添加动态库文件的名称,例如“mylib.dll”。 8. 在代码中包含动态库头文件,然后使用动态库中的函数和变量。 下面是一个使用动态库的示例: 1. 假设你的动态库名称为 `mylib.dll`,头文件名为 `mylib.h`。 2. 将 `mylib.h` 头文件添加到你的项目中。 3. 将 `mylib.dll` 文件放到一个合适的位置,例如项目目录下的 `lib` 文件夹。 4. 打开项目属性页,选择“VC++ 目录”选项卡,然后将 `lib` 文件夹路径添加到“库目录”中。 5. 选择“链接器”选项卡,然后在“附加依赖项”中添加 `mylib.dll` 的名称。 6. 在代码中包含 `mylib.h` 头文件,然后使用动态库中的函数和变量。 以下是一个使用动态库的示例代码: ```c++ #include <iostream> #include <Windows.h> #include "mylib.h" int main() { // 加载动态库 HMODULE handle = LoadLibraryA("mylib.dll"); if (handle == NULL) { std::cerr << "Failed to load dynamic library: " << GetLastError() << std::endl; return 1; } // 获取动态库中的函数指针 typedef int (*mylib_func_t)(int); mylib_func_t mylib_func = (mylib_func_t) GetProcAddress(handle, "mylib_func"); if (mylib_func == NULL) { std::cerr << "Failed to find symbol in dynamic library: " << GetLastError() << std::endl; return 1; } // 调用动态库中的函数 int result = mylib_func(42); std::cout << "Result: " << result << std::endl; // 卸载动态库 FreeLibrary(handle); return 0; } ``` 在这个示例中,我们使用 `LoadLibraryA()` 函数加载动态库,并使用 `GetProcAddress()` 函数获取名为 `mylib_func` 的函数指针。最后,我们通过调用 `mylib_func()` 函数来使用动态库。在使用动态库后,我们使用 `FreeLibrary()` 函数卸载动态库。注意,Windows API 中动态库的函数名需要使用 `GetProcAddress()` 函数来获取,而不是直接使用函数名。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值