You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

导入的库函数内存会移动吗?库未卸载重载时函数地址是否始终不变?

Windows动态库函数地址相关问题解答

问题1:导入的库函数在内存中是否会被移动?

在Windows系统下,只要动态库(DLL)没有被卸载或重新加载,库中的函数在内存中的位置就不会被移动。

具体来说:

  • 当你通过LoadLibrary加载DLL时,系统会先尝试将它加载到DLL本身指定的「首选基地址」(这个地址是编译DLL时设置的)。如果这个地址没有被进程中的其他模块占用,DLL就直接加载到这里,函数的内存位置就是固定的。
  • 如果首选基地址被占用了,系统会自动对DLL进行重定位,把它加载到进程地址空间中的另一个空闲区域。这个重定位操作是在加载阶段完成的,一旦DLL加载完成,它在内存中的位置就完全固定了,不会在程序运行过程中被动态移动。

问题2:假设动态库未被卸载和重载,指向库中函数的函数地址在整个程序执行期间是否会保持不变?

答案是肯定的,只要满足「DLL未被卸载、未被重新加载」这个前提,你通过GetProcAddress获取的函数指针就会始终有效,地址不会发生变化。

看你给出的代码示例:

HMODULE hm = LoadLibrary("SomeLibrary.dll"); 
SomeFunction fn = (SomeFunction)GetProcAddress(hm, "SomeFunction"); 
fn(arg1, arg2); // 该fn在整个执行期间是否始终有效?

只要你没有调用FreeLibrary(hm)卸载这个DLL,也没有在模块被卸载后再次调用LoadLibrary("SomeLibrary.dll")(重复加载可能导致模块地址变化,不过同一进程中未卸载时重复加载会返回同一个模块句柄),fn这个函数指针就可以安全地在程序整个生命周期中使用,每次调用都会指向同一个内存地址的函数。

需要额外注意的是:如果DLL被卸载后重新加载,哪怕是同一个DLL,新加载的模块可能会被放到不同的内存地址,这时候之前保存的函数指针就失效了,必须重新调用GetProcAddress获取新的地址。


内容的提问来源于stack exchange,提问作者Joseph Hurti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:33:19