普通 Windows API 里,我们常用 LoadLibrary 加载 DLL,再用 GetProcAddress 找导出函数。AHK_H 还提供了 MemoryLoadLibrary()、MemoryGetProcAddress()、MemoryFreeLibrary() 这一组函数,用来把 DLL 作为内存模块加载并调用。
它的重点不是“神秘”,而是多了一个加载方式:可以类似 LoadLibrary 那样拿到模块句柄,又可以允许同一个模块以不同内存模块形式加载多次。实际使用时,仍然要理解导出函数、函数指针、参数类型和释放时机。
最小调用结构
#Requires AutoHotkey v1.1
#NoEnv
SetBatchLines, -1
dllPath := A_AhkDir "\AutoHotkey.dll"
mod := MemoryLoadLibrary(dllPath)
if (!mod) {
MsgBox, MemoryLoadLibrary 加载失败
ExitApp
}
pAhkTextDll := MemoryGetProcAddress(mod, "ahktextdll")
pAhkReady := MemoryGetProcAddress(mod, "ahkReady")
if (!pAhkTextDll || !pAhkReady) {
MemoryFreeLibrary(mod)
MsgBox, 找不到需要的导出函数
ExitApp
}
code := "#Persistent`nMsgBox, 来自 MemoryLoadLibrary 加载的 AutoHotkey.dll"
DllCall(pAhkTextDll, "Str", code, "Str", "", "Str", "MemThread", "CDecl Ptr")
While DllCall(pAhkReady)
Sleep, 100
MemoryFreeLibrary(mod)
它和 LoadLibrary 的区别
LoadLibrary是 Windows 常规 DLL 加载方式。MemoryLoadLibrary是 H 版提供的内存模块加载方式,文档说明它类似LoadLibrary,但从内存模块加载,并允许同一模块加载多次。GetProcAddress对应的是MemoryGetProcAddress()。FreeLibrary对应的是MemoryFreeLibrary()。
实际用途
- 测试 AutoHotkey.dll 的导出函数,不想和当前已加载模块混在一起。
- 一个进程里需要多份相对独立的 DLL 模块状态。
- 配合 H 版资源加载,把 DLL 作为资源或内存模块使用。
- 写高级封装时,需要通过函数指针调用导出函数。
不是万能方案
MemoryLoadLibrary() 很强,但不代表所有 DLL 都适合这样加载。某些 DLL 依赖系统加载器行为、依赖其它 DLL、依赖特定初始化流程,内存加载时可能出现兼容问题。新手应先用普通 LoadLibrary 跑通,再考虑 Memory 系列函数。
mod := MemoryLoadLibrary(A_ScriptDir "\MyLibrary.dll")
if (!mod)
throw Exception("DLL 加载失败")
pFunc := MemoryGetProcAddress(mod, "MyExportedFunction")
if (pFunc)
result := DllCall(pFunc, "Int", 123, "Int")
MemoryFreeLibrary(mod)
使用建议
- 只调用自己信任的 DLL,不要把来源不明的二进制模块塞进脚本。
- 确认位数一致:32 位脚本配 32 位 DLL,64 位脚本配 64 位 DLL。
- 每次
MemoryLoadLibrary()后都要安排MemoryFreeLibrary()。 - 函数指针调用时,
DllCall的参数类型和返回类型要严格对应导出函数。 - 如果 DLL 是放在脚本资源里,也可以继续研究 H 版的
ResourceLoadLibrary()。
一句话总结
MemoryLoadLibrary 适合高级封装和模块隔离场景。入门阶段先理解“加载模块、找函数地址、DllCall 调用、释放模块”这条链路,就已经能看懂大部分 H 版内存加载 DLL 示例。
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。

评论(0)