如何解决64 位托管进程:进程外 32 位 COM 服务器非默认接口不可用
我正在将最初用 VB6 编写的 Excel 加载项迁移到托管代码和 64 位 Excel。该加载项通过 COM 代理与一些旧的 32 位 COM DLL 服务器进行互操作,并且遇到了一个问题,即在运行时只有协同类各自默认接口中的方法和属性可用。尝试调用组件公开的任何其他接口中的方法和属性会导致 System.MissingMethodExceptions。
当迁移的加载项与 32 位 Excel 一起使用并且服务器在进程中运行时,非默认接口可用。
是否可以采取任何措施使 64 位模式下的加载项可以使用非默认接口?
解决方法
解决方案是使用类型库封送处理(也称为通用封送处理),使用系统提供的 oleaut32.dll 中的封送处理引擎。通用封送拆收器可用于任何自定义接口,前提是参数与变体兼容。
要为接口使用通用封送拆收器,接口被标记为oleautomation,如下例接口所示:
[
object,oleautomation,uuid(23D4EC0B-96DA-4D18-82BD-40E3AA0483FD),version(1.0),dual,helpstring("Description of ICustomInterface1"),pointer_default(unique)
]
interface ICustomInterface1 : IDispatch
{
// Methods and properties …
}
通用封送处理还需要以下注册表项:
-
HKCR\TypeLib
-
HKCR\TypeLib\0
-
HKCR\TypeLib\0\win32 = “类型库文件的路径”
-
HKCR\TypeLib\Flags
-
HKCR\TypeLib\HelpDir = “帮助文件夹的路径”
-
[HKEY_CLASSES_ROOT\Interface
@="接口名称" -
[HKEY_CLASSES_ROOT\Interface\ProxyStubClsid32 ="{00020424-0000-0000-C000-000000000046}"
HKCR\Interface
使用此类型信息,通用封送拆收器在运行时创建代理存根,无需自定义代理存根 DLL。
在我们的例子中,鉴于组件是基于 ATL 的,一旦接口被标记为“oleautomation”并重建组件,就会自动创建注册表条目。对于非 ATL 项目,这可以通过 Win32 API 的 LoadTypeEx()(我没有尝试过)以编程方式完成。
一旦完成,我们基于 ATL 的组件的非默认接口就可以在我们迁移到 VB.NET 的 Excel COM 加载项的进程外使用。
“COM 和 ATL 3.0 开发人员研讨会”第 5 章详细介绍了所有这些。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。