我很难理解为什么 C++ 中同时需要 #include 和 LoadLibrary()。在 C++ 中,“#include”强制预处理器将 #include 行替换为您包含的文件的内容(通常是包含声明的头文件)。据我了解,这使我能够在 header 所属的外部库中使用我可能想要的例程。
为什么我需要 LoadLibrary()?我不能只#include 库本身吗?
顺便说一句:在我更熟悉的 C# 中,如果我想在我的程序中使用该 DLL 中的类型或例程,我只需添加对 DLL 的引用。我不必#include 任何东西,因为.NET 框架显然会自动搜索所有引用的程序集以查找我想要使用的例程(由命名空间指定)
非常感谢您提前。
编辑:使用了“定义”这个词,但意思是“声明”。现在修好了。
编辑2:很难选择一个答案,很多好的回复。感谢所有的贡献。
最佳答案
C++ 使用完全独立的编译模型;你甚至可以编译
针对尚未编写的代码。 (这经常发生在
大型项目。)当你包含一个文件时,你所做的就是
告诉编译器函数等存在。你不
提供一个实现(内联函数和
模板)。为了执行代码,您必须提供
实现,通过将其链接到您的应用程序。这
可以以几种不同的方式发生:
源,并链接到生成的对象中。
取决于实现:在Windows下,你必须链接
针对 .lib stub ,并将 .dll 放在
运行时会在您执行时找到它。 (把它放在同一个
目录,因为您的应用程序通常是一个很好的解决方案。)
我不太明白您需要调用
LoadLibrary
.这我唯一需要的时候是我故意避免
直接使用库中的任何内容,并希望加载它
有条件地使用
GetProcAddr
获取地址我需要的功能。
编辑:
由于我被要求澄清“链接”:程序翻译
(从源代码到可执行文件)发生在多个
脚步。在传统术语中,每个翻译单元都是
“编译”成一个目标文件,其中包含一个图像
机器指令,但有未填充的空间用于外部
引用。例如,如果您有:
extern void function();
在您的来源中(可能通过包含标题),并且您
调用
function
,编译器会留下地址字段调用指令空白,因为它不知道在哪里
功能将被定位。链接是采取一切的过程
的目标文件,并填写这些空白。中的一个
目标文件将定义
function
,并且链接器将在内存镜像中建立实际地址,并填写
引用
function
的空白地址为function
在那个图像中。结果是完整的内存镜像可执行。在我工作的早期系统上:字面意思。这
操作系统只需将可执行文件直接复制到内存中,
然后跳进去。诸如虚拟内存和共享之类的东西,
编写 protected 代码段使这更多
今天很复杂,但对于静态链接的库或对象
文件(我上面的前两个案例),差异不在于
伟大的。
现代系统技术在某种程度上模糊了界限。为了
例如,大多数 Java(我认为是 C#)编译器不会生成
经典的目标文件,带有机器码,而是字节码,
以及上面的编译和链接阶段,直到
运行。一些 C++ 编译器也只生成字节码,
将在代码“链接”时编译。这是为了
允许跨模块优化。以及所有现代系统
支持动态链接:留一些空白地址
空白直到执行时间。动态链接可以是隐式的
或显式:当它是隐式时,链接阶段将插入
信息到有关它的库的可执行文件中
需要,在哪里可以找到它们,操作系统将链接它们,
隐式地,无论是在加载可执行文件时,还是在需要时,
由尝试使用未填充之一的代码触发
地址槽。当它是明确的时,你通常没有任何
在您的代码中显式引用了该名称。如果是
function
,例如,你不会有任何代码直接调用
function
.但是,您的代码将加载使用
LoadLibrary
的动态库(或 dlopen
在 Unix 下),然后使用
GetProcAddr
请求名称的地址(或者dlsys
),并通过指针间接调用函数它收到了。
关于C++:包含与 LoadLibrary(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20076600/