在 64 位服务中使用 32 位 DLL 的指针

本文关键字:DLL 指针 服务 | 更新日期: 2023-09-27 18:34:49

直到最近,我们还以x86的形式运行服务,但将其更改为任何CPU,以使用64位DLL引入一些新功能。第三方DLL的剩余部分之一是32位。我在注册表中为它设置了一个 DLL 代理项,但这只是解决方案的一半。

我怀疑在内存中创建的指针无法访问,因为它不再在 Proc 中运行。我需要知道的是如何使用 System.Runtime.InteropServices.Marshall 对象来访问返回的指针。

提前谢谢。

public Image GetThumbnail(string strFilename)
    {
        SeThumbnailExtractor objExtractor = new SeThumbnailExtractor();
        int hImageSE;
        Image objImage = null;
        try
        {
            objExtractor.GetThumbnail(strFilename, out hImageSE);
            IntPtr iPImage = new IntPtr(hImageSE);
            //fails below
            objImage = Image.FromHbitmap(iPImage);
            _ReturnedImage = objImage;
            _SourceFile = strFilename;
            Marshal.FreeHGlobal(iPImage);
        }
        catch (Exception ex)
        {
            _ErrorMsg = "ERROR: " + ex.Message.ToString();
        }
        if (objExtractor != null)
        {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(objExtractor);
            objExtractor = null;
        }
        return objImage;
    }

在 64 位服务中使用 32 位 DLL 的指针

在代理项中运行对于正确实现的 COM 组件是完全透明的。 组件的代理/存根可确保代理将接口方法的参数和返回值正确序列化为互操作数据包,以便可以跨进程划分传输并在存根中再次反序列化。

然而,"正确实施"是问题所在。 如果从COM方法获取原始位图句柄或指针,则肯定会带来麻烦。 句柄或指针不能序列化,它仅在创建它的进程中有效。 需要一个自定义代理/存根,该代理/存根将该句柄替换为实际位图数据,并将该数据传输到存根,以便可以在 64 位进程中使用新的句柄/指针重新创建位图。

COM 组件作者处理的几率很小,这并不容易做到,而且他当时肯定没有看到要求,因为他认为该组件将始终在进程中使用。 现在不是了。

没有简单的解决方法,您必须创建一个适当的代理/存根,这至少需要访问组件的原始 IDL。 通常只有 COM 作者才能访问它。 坏消息,我敢肯定。

一种可能的解决方法是将其留给 .NET 来处理它。 你将需要一个在 32 位模式下运行的帮助程序进程,以便可以毫无问题地加载 COM 组件。 使用一种 .NET 互操作机制(如 WCF 或远程处理(与它通信。 序列化位图现在完全掌握在您手中。