Walkthrough: Create and use your own Dynamic Link Library (C++)

本文翻译自:Walkthrough: Create and use your own Dynamic Link Library (C++)

这是微软官方的资料,显然针对Windows和Microsoft Visual Studio.

本文包括以下内容:
(1) 通过Visual Studio创建一个DLL项目
(2) 向DLL增加输出的函数和变量。
(3) 用Visual Studio创建一个控制台应用
(4) 在控制台App中引用DLL中的函数和变量。
(5) 运行完整的APP

一个DLL文件按照名称导出变量、函数、资源。一个客户APP引用这个名字去使用那些变量、函数和资源。Windows在加载时或运行时将应用程序中的导入连接到DLL中的导出,而不是在链接时连接它们。Windows需要标准C++编译模型之外的额外信息来建立这些连接。

本文提供了两个Visual Studio的解决方案,一个建立了DLL文件,另一个建立了客户APP。DLL使用C调用规约。它可以从用其他编程语言编写的应用程序中调用,只要平台、调用规约和链接规约匹配。

第一步: 创建DLL项目
选择这个:
在这里插入图片描述
在项目中创建一个新的头文件,在其中写入类似于这样的内容:

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

#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __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();

请注意文件顶部的预处理器语句。DLL项目的新项目模板将_EXPORTS添加到定义的预处理器宏中。在这个例子中,Visual Studio在构建MathLibrary DLL项目时定义MATHLIBRARY_EXPORTS。
当定义MATHLIBRARY_EXPORTS宏时,MATHLIBRARY_API宏会在函数声明上设置__declspec(dllexport)修饰符。这个修饰符告诉编译器和链接器从DLL中输出函数或变量以供其他应用程序使用。

第二步: 增加对DLL的实现
在之前的头文件的基础上,编写类似于下面这样的.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_;
}

点击生成—>生成解决方案,得到类似于下面的结果:

1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------
1>pch.cpp
1>dllmain.cpp
1>MathLibrary.cpp
1>Generating Code...
1>   Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

更新: 再试着看看后面的内容。

第三步: 创建一个使用这个DLL的客户端APP
当你创建一个DLL时,考虑客户端如何使用它。为了调用DLL输出的函数或访问DLL输出的数据,在编译时间客户端源代码必须有可用声明。在链接时,链接器需要信息来解析函数调用或数据访问。DLL在一个导入库(一个包含如何查找函数和数据的信息的文件)中提供这些信息,而不是实际的代码。在运行时,DLL必须在操作系统可以找到的位置对客户端可用。

不论是你自己的或来自一个第三方,你的客户端APP项目需要一些信息以便使用DLL。它需要找到声明DLL导出的头文件、链接器的导入库和DLL本身。一个方法是把所有这些文件复制到客户端项目。对于在客户端开发过程中不太可能更改的第三方dll,这种方法可能是使用它们的最佳方式。然而,当你也构建DLL时,最好避免重复。

为避免代码不同步,我们建议您将客户端项目中的包含路径设置为直接从DLL项目包含DLL头文件。另外,在客户端项目中设置库路径,以包含来自DLL项目的DLL导入库。最后,将构建的DLL从DLL项目复制到您的客户机构建输出目录中。此步骤允许您的客户端应用程序使用您构建的相同DLL代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值