DLL那些事儿(一)

我们将讨论:

  • 如何构建DLL
  • 如何在项目中使用DLL
  • DLL里面有什么
  • 显式(Explicit)和隐式(implicit)链接
  • 当你加载DLL时发生了什么
  • 如何诊断DLL加载失败
  • 指定DLL输出(export)内容的各种方法
  • 数据导出
  • 延迟加载
  • C++和DLLs
  • 线程和TLS
  • DLL地狱(Hell)

我们不讨论:

  • 其他平台上的动态库或共享对象
  • .Net 程序集或其他.Net相关主题
  • 资源DLL

什么是动态库:

  • …它包含代码和数据。
  • …它能在程序运行时动态加载。
  • …可以被多个程序共享或重用。

大多数动态库的扩展名都是 “.dll”

使用DLL有什么好处

多个程序可以共享代码和数据,而不需要每个程序都有自己的副本

  • 可以节省磁盘空间的使用
  • 可以节省内存的使用

可以在运行时决定是否加载某个功能

  • 也许你不总是需要一些功能
  • 也许你想支持开放式扩展(例如插件)

可维护性

  • 通过DLL实现组件化
  • 提高了可服务性(bug修复,安全补丁等)
  • 提高了可维护性

使用DLL的缺点

软件发行变得更复杂

  • 如果你将所有的东西放进单个EXE中,那么安装起来就很容易

增加了不兼容的可能性(DLL Hell)

不可能跨DLL边界优化代码

  • 每一次跨DLL边界的调用必须是间接的
  • (但是使用DLL也有性能上的好处)

创建一个小的DLL

// Hello.cpp
extern "C" char const* __cdecl GetGreeting()
{
        return "Hello, C++ Programmers!";
}

使用VS构建工具进行编译和链接,我们使用/c选项告诉编译器只进行编译

使用/DLL选项告诉链接器不要构建exe(默认选项)而是构建一个dll, 使用/NOENTRY选项使得链接时去掉一些不必要的东西,简化导出的dll,使用/EXPORT选项告诉链接器“GetGreeting”是DLL中公开的接口

F:\learning\VsProject\dllproject>cl /c Hello.cpp
Hello.cpp
F:\learning\VsProject\dllproject>link Hello.obj 
											/DLL 
											/NOENTRY 
											/EXPORT:GetGreeting
 正在创建库 Hello.lib 和对象 Hello.exp								

这样我们就得到了Hello.dll,接下来我们使用这个动态库

// PrintGreeting.cpp
#include <Windows.h>
#include <stdio.h>

int main()
{
	HMODULE const HelloDll = LoadLibraryExW(L"Hello.dll", nullptr, 0);
	
	// char const* __cdecl GetGreeting();
	using GetGreetingType = char const* (*__cdecl)();

	GetGreetingType const GetGreeting = 
        reinterpret_cast<GetGreetingType>(GetProcAddress(HelloDll, "GetGreeting"));

	puts(GetGreeting());

	return 0;
}

编译并运行这个cpp,我们看到这个程序正常工作,并且输出了“Hello, C++ Programmers!”

F:\learning\VsProject\dllproject>cl PrintGreeting.cpp

/out:PrintGreeting.exe
PrintGreeting.obj

F:\learning\VsProject\dllproject>PrintGreeting.exe
Hello, C++ Programmers!

参考链接:

https://nullprogram.com/blog/2018/11/21/

https://www.youtube.com/watch?v=JPQWQfDhICA

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值