0

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

我怀疑在内存中创建的指针不可访问,因为它不再在进程中运行。我需要知道的是如何使用 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;
    }
4

1 回答 1

2

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

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

COM 组件作者解决这个问题的可能性很小,这并不容易,而且他当时肯定没有看到需求,因为他认为组件将始终在进程中使用。现在不是了。

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

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

于 2013-10-10T13:04:18.623 回答