我正忙于编写一个为主机应用程序提供多种功能的DLL。 该应用程序动态调用dll,在每次函数调用后加载并释放它。德尔福动态Dll - 全局变量
我无法控制主机应用程序。我只能在dll内工作。 有没有办法让内存中的某些变量保留下来,以便我可以在每个函数中重用它们?很明显,当主机应用程序卸载dll时,全局可变数据就会被清除。 保存DLL文件听起来非常混乱!
任何人都可以提出一种方法来分配一个变量,我可以保持全球?
谢谢
我正忙于编写一个为主机应用程序提供多种功能的DLL。 该应用程序动态调用dll,在每次函数调用后加载并释放它。德尔福动态Dll - 全局变量
我无法控制主机应用程序。我只能在dll内工作。 有没有办法让内存中的某些变量保留下来,以便我可以在每个函数中重用它们?很明显,当主机应用程序卸载dll时,全局可变数据就会被清除。 保存DLL文件听起来非常混乱!
任何人都可以提出一种方法来分配一个变量,我可以保持全球?
谢谢
我认为你在这里有两个主要选项。
报价2版本的功能,你现在有一个,加上另一个地方,他们在缓冲区(记录,等等),你可以读取以前的状态,当然更新状态为通过。称这是函数的高性能版本。他们会想要使用它。
保存喜欢你的状态会一个cookie(那基本上它是什么)在文件中的某个地方。
选项1将需要修改主机应用程序,但将是引人注目的主机应用程序开发人员采取的,选项2优点将不需要改变到主机应用程序,但不会像高性能的。
我不会亲自倾向于开始摆弄引用计数,想必主机应用程序正在卸载是有原因的,如果我是主机应用开发,这将激怒了我。
谢谢 - 我认为这是最好的选择。 我宁愿保存到文件并采取性能比风险而不是摆弄dll引用。也许主机应用程序开发人员将继续提供高性能版本 – Crudler 2009-06-26 12:30:27
最好的方法是使用包含“全局变量”的类。您实例化一个对象并将其作为参数提供给dll函数。但这不会帮助你,因为你无法更改调用应用程序。
如果你必须保持全局数据在DLL中,一个解决方案是将它们写入文件。但这对性能造成严重影响。
如果我是你,我会的全局变量的值保存到一个文件时,该dll被释放,当它被初始化加载它们。我没有理由保存磁盘上的DLL的内存转储。
警告,肮脏的黑客:
您可以加载自己。
每次调用LoadLibrary
递增引用计数器,FreeLibrary
递减它。只有当计数器达到零时,DLL才会被卸载。
因此,如果第一次你的DLL被加载时,你又把您的书架,从而增加引用计数器。如果调用应用程序调用FreeLibrary
引用计数器递减,但该DLL不会被卸载。
编辑:正如mghi指出,如果进程终止,DLL是否会被卸载,引用计数是否为零。
如果你有大量的全局数据要共享,另一个解决方案是创建一个windows服务来“缓存”状态数据。您还需要实现某种跨越进程边界的IPC,例如内存映射文件,邮箱,COM(本例为单实例),TCP/IP等。您可能会发现这种开销不仅仅是将状态写入文件,这就是为什么我只会在状态数据量过多时才推荐这种方法,或者只会在每个请求的整个部分处理这些数据进入你的dll。
对于COM方法,除了请求(并保持)将用于维护状态的com对象的实例之外,服务不必做太多的事情。由于它是一个单实例com对象,因此所有请求都将发送给同一个实例,从而允许您在请求之间保存状态。对该对象的请求将被序列化,因此,如果您有多个客户端同时在同一台计算机上请求数据,则这可能是性能问题。
当DLL被释放时将值写入注册表,并且在加载DLL时从注册表读取值。当读取发现没有设置密钥时,不要忘记提供默认值。
-Al。
我同意之前关于全球状态信息危险的评论,尽管我可以想象它可能是需要的。
我提出DR的肮脏的黑客更清洁的版本不具有作为永久像skamradt的回答的缺点:
一个非常小的应用程序:
它没有外观无论如何,它让自己从显示在任务栏上。
任务#1:加载DLL
任务#2:把它的命令行,运行它,并等待它终止。
任务#3:卸载DLL
任务#4:退出。
安装程序:
它找到快捷方式(多个)到主应用程序,并修改它们所以小应用程序运行时,原始位置的快捷指向变成第一参数。
结果:只有主应用程序正在运行,DLL才会保留在内存中,但每次程序转储时它都不会被卸载。
这也可能是有益的
option 1:
创建握着你的页面文件支持的变量共享内存区 - 如果你能打开共享内存区,你的DLL以前加载(假设“私人“共享内存名称,可能名称与process_id_yourdllname类似) - 如果您无法打开它,那么您首次创建并初始化它。如果你创建了它,那么你不用去删除它 - 但是如果你打开它,你会在卸载时关闭它。我相信当应用程序关闭时该区域将被释放,因为没有其他应用程序应该处理这个特定的“私有”共享内存区域。
option 2:
创建第二个。只存在用于管理全局变量的dll。你的DLL A可以加载该DLL B,而不是释放它,放入DLL B无论你需要管理全局变量。当应用程序消失时它应该消失,我认为你可能不需要关心(可能是无用的)引用计数(因为你不会卸载dll B)。
您的设计很糟糕,原因很多。你有没有想过多个主机应用程序(快速用户切换,在终端服务器下使用)或主机应用程序从多个线程调用DLL函数的可能性?不惜一切代价尽量避免全局/共享状态。 – mghie 2009-06-25 09:45:47