COM 对象 DLL 加载问题
我正在开发一个 Qt DLL,用作大型应用程序的插件。该 DLL 依赖于其他 DLL,遗憾的是这些 DLL 并不位于同一文件夹中,因此只有在正确设置当前工作目录时才会加载(大型应用程序在对 DLL 调用 LoadLibrary
之前会执行此操作) 。我无法控制这种行为。
我被要求向这个插件添加一个简单的 COM 对象,我已经完成了,但我现在遇到的问题是,除非当前工作目录设置正确,否则 DLL 无法注册或由第 3 方应用程序使用 - 因为任何LoadLibrary 调用失败。显然,我无法控制第 3 方应用程序使用的当前工作目录,并且在现阶段我不允许修改 PATH 以确保可以找到依赖项。
我已尝试对依赖的 DLL 使用 /DELAYLOAD
但失败并出现“由于导入数据符号而无法延迟加载 foo.dll...”错误。同样,我无法轻易改变这些依赖 DLL 的使用方式。
目前,我认为唯一的解决方案是将 COM 对象移动到一个不依赖于其他任何东西的独立 DLL 中,但我面临着寻找解决方案并将 COM 对象保留在插件 DLL 中的压力。我不明白这怎么可能,所以我想看看其他人是否有任何想法。某种形式的系统范围 SetDllDirectory
调用会有所帮助,或者当第 3 方应用程序在我的插件上调用 LoadLibrary
时,某些注册表黑客可以设置工作目录。
I am working on a Qt DLL that is used as a plugin for a large application. This DLL depends on other DLLs that are sadly not located in the same folder and hence will only load if the current working directory has been set correctly (which the large application does prior to calling LoadLibrary
on the DLL). I have no control over this behaviour.
I have been asked to add a simple COM object to this plugin which I have done but I now have the problem that the DLL cannot be registered or used by a 3rd-party application unless the current working directory is set correctly - because any LoadLibrary
calls on the plugin fail due to the missing dependencies. Obviously I have no control over the current working directory used by 3rd-party apps and at this stage I am not allowed to modify the PATH to ensure the dependencies can be found.
I have tried using /DELAYLOAD
for the dependent DLLs but this fails with 'cannot delay-load foo.dll due to import of data symbol...' errors. Again, I cannot easily change the way these dependent DLLs are used.
Currently I think the only solution is to move the COM object into a stand-alone DLL that doesn't depend on anything else but I am under pressure to find a solution and leave the COM object in the plugin DLL. I can't see how this is possible so I thought I'd see if anyone else has any ideas. Some form of system-wide SetDllDirectory
call would help or some registry hack that could set the working directory when a 3rd-party app calls LoadLibrary
on my plugin.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
IMO 将 COM 对象分离到单独的 .dll 中是最干净的解决方案 - 任何人都希望使用 regsvr32 注册进程内 COM 服务器,并且不需要该 COM 服务器中的任何花哨的依赖项。
IMO separating the COM object into a separate .dll is the cleanest solution - anyone would expect an in-proc COM server to be registered by using
regsvr32
and that requires no fancy dependencies in that COM server.我不知道这是否正是您问题的解决方案,但这也许可以帮助您:尝试查看清单文件提供的可能性。我希望它会有所帮助。
I don't know if it's precisely a solution to your problem, but maybe this can help you: try to look at the possibilities offered by manifest files. I hope it will help.
您可以使用运行时注册模型。
Dll 可以在自己的初始化代码中将自己注册为 COM 服务器。
这仅要求在将dll用作COM服务器之前保证调用loadlibrary。
You could use a runtime registration model.
The Dll could register itself as a COM server in its own initialisation code.
This only requires that loadlibrary is guaranteed to be called before the dll is used as a COM server.