在程序运行时更改 DLL
Posted
技术标签:
【中文标题】在程序运行时更改 DLL【英文标题】:Changing a DLL while a program is running 【发布时间】:2019-06-18 05:00:41 【问题描述】:我一直想用 C++ 制作一个关于编程小船一起战斗的游戏。
不过,其中一件事是我希望能够在游戏运行时对其进行编辑,而不必退出并重新编译整个游戏。我父亲告诉我,我可以使用 DLL 来执行此操作,通过让游戏复制选定的 DLL 文件并从中运行函数,然后在游戏中当我按下重新加载时,它将停止脚本并复制新的 DLL 和继续游戏。
为了测试这个想法,我在 Codeblocks 中制作了一个简单的程序和 DLL 项目。控制台程序从 DLL 调用了一次函数thisIsAFunction()
,它会返回一个数字以打印到控制台,例如“1”,然后我会将 DLL 文件替换为另一个具有相同函数名称但返回的 DLL 文件一个不同的数字打印到控制台。
它不工作。尝试在控制台应用程序运行时替换 DLL 文件或 library.a
文件,Windows 说它在另一个进程中打开。
有什么方法可以完成我想做的事情吗?也就是说,在使用 DLL 文件或其他任何东西的程序期间更改函数返回值?
编辑:首先感谢 Remy Lebeau 帮助修复所有语法错误。我将很快收集代码以供参考,但似乎你们中的一些人建议使用脚本语言代替,这也可能有效。所以谢谢你我也会调查的。那么,用 DLL 解决所有麻烦真的值得吗,还是我真的应该只使用 Python 或 Lua 之类的东西?
【问题讨论】:
在没有看到任何代码的情况下很难判断你做错了什么。请发帖minimal reproducible example。 我很确定您必须先卸载 DLL,然后才能覆盖 DLL 文件。这就是我在 VS 中所认识到的一般情况:在使用 DLL 时(在正在运行的应用程序中)该文件不能被删除或覆盖。我想知道您对 lib 的担忧。对于插件(在运行时使用LoadLibrary()
加载),我们使用GetProcAddress()
提取函数指针。编译时需要一个 lib 文件,但插件是与可执行文件分开编译/链接的(因此不涉及 lib 文件)。
我曾经为SO: difference between Load DLL and Direct Call 写了一个答案,为SO: GetProcAddress vs __declspec( dllimport ) 写了一个更长的答案,这可能会有所帮助。
我认为您最好采用另一种方法,例如为该部分使用 LUA 或其他引擎。见lua.org
这可能也很有趣:SO: Update a dll without stopping the service(尽管它不会改变已经声明的内容)。
【参考方案1】:
这个想法理论上是可行的,但是...
您不能使用简单的 DLL 支持,因为它会加载一次 thisIsAFunction()
。您需要在更改 DLL 后重新加载该函数。这是一个手动过程。您必须致电LoadLibrary
、GetProcAddress
和FreeLibrary
。
此外,除了函数之外,您还需要确保所有由 DLL 创建的对象都已消失。由于您卸载了 DLL,因此您也卸载了其中的所有析构函数,因此所有需要这些析构函数的对象都必须在析构函数仍在加载时被销毁。
【讨论】:
以上是关于在程序运行时更改 DLL的主要内容,如果未能解决你的问题,请参考以下文章
在运行时从另一个 AppDomain 调试动态加载的 DLL