且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Delphi静态或动态链接到windows dll

更新时间:2023-09-12 14:37:34

两种形式的DLL链接可能更好地称为隐式和显式。隐式连接是您所指的静态链接。而显式连接就是你所指的运行链接。



对于隐式链接,链接器将条目写入可执行文件的导入表中。此导入表是加载程序用于在模块加载时解析DLL导入的元数据。每个隐式导入都包含一个stub函数,该引用只有几个字节大小。隐式链接的可执行大小含义可以忽略不计。



通过显式链接,导入的函数的地址通过调用GetProcAddress来解决。这个调用是在程序员选择时进行的。如果DLL或函数无法解析,程序员可以编写回退行为。对于我估计与隐式链接相似的显式链接,有大小的影响。如果功能地址被评估一次并且在调用之间记住,则性能特征与隐式链接相似。



我的建议如下:


  1. 喜欢隐式链接。代码更方便。

  2. 如果DLL可能不存在,请使用显式链接。

  3. 如果DLL必须使用完整的路径,使用显式链接。

  4. 如果要在程序执行期间卸载DLL,请使用显式链接。

您特别提到Windows DLL。你可以放心地假设他们会在场。不要尝试代码来允许程序运行,以防万一user32.dll丢失。旧版本的Windows中可能不存在某些功能。如果您支持这些旧版本,则需要使用显式链接并提供后备。决定您支持哪个版本并使用MSDN确保您的最低支持平台上的功能可用。


I am aware that implicitly linking to libraries at load time can lead to performance increases and as such I was wondering if it was good practice to link in this way at compile time thus increasing executable size (admittedly this is only marginal) compared to linking explicitly at runtime. My question is when linking against Microsoft Windows dll files located in System32, is it 'better' to link at load time as you can be mostly certain that the libraries will be present or follow the explicit approach?

Language used is Delphi (pascal) and the library in question is the WTsAPI32.dll - Terminal Services.

EDIT: As pointed out - my choice of language was incorrect and has been amended. Also, due to having only really every extensively linked to libraries in Unix, my comments about executable size can be omitted, I believed at the time I WAS in fact referring to static linking which bundles the library code into the executable and I now realise this is impossible when using dll files (DUH!). Thanks all.

The two forms of DLL linking are perhaps better named implicit and explicit. Implicit linking is what you refer to as static linking. And explicit linking is what you refer to as runtime linking

For implicit linking the linker writes entries into the import table of the executable file. This import table is metadata that is used by the loader to resolve DLL imports at module load time. A stub function is included for each implicit import that is only a few bytes in size. The executable size implications of implicit linking are negligible.

With explicit linking the imported function's address is resolved by a call to GetProcAddress. This call is made when the programmer chooses. If the DLL or the function cannot be resolved, the programmer can code fall back behaviour. There are size implications to explicit linking that I estimate to be similar to implicit linking. If the function address is evaluated once and remembered between calls then the performance characteristics are similar to implicit linking.

My advice is as follows:

  1. Prefer implicit linking. It is more convenient to code.
  2. If the DLL may not be present, use explicit linking.
  3. If the DLL must be loaded using a full path, use explicit linking.
  4. If you want to unload the DLL during program execution, use explicit linking.

You specifically mention Windows DLLs. You can safely assume that they will be present. Don't try to code to allow your program to run in case user32.dll is missing. Some functions may not be present in older versions of Windows. If you support those older versions you'll need to use explicit linking and provide a fallback. Decide which version you support and use MSDN to be sure that a function is available on your minimum supported platform.