直到最近,我们正在运行x86服务,但将其更改为使用任何CPU使用64位DLL引入一些新功能。其中一个剩下的第三方DLL是32位。我在注册表中为它设置了一个DLL代理,但这只是解决方案的一半。
我怀疑在内存中生成的指针是不可访问的,因为它不再在inProc中运行。我需要知道的是如何使用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;
}
答案 0 :(得分:2)
在代理中运行对正确实现的COM组件完全透明。组件的代理/存根确保接口方法的参数和返回值由代理正确地序列化为互操作数据包,以便它可以在进程鸿沟中传输并在存根中再次反序列化。
然而,“正确实施”是一个难题。如果从COM方法获得原始位图句柄或指针,那么肯定会造成麻烦。句柄或指针不能被序列化,它只在创建它的过程中有效。需要一个自定义代理/存根,用该实际的位图数据替换该句柄,将该数据传输到存根,以便在64位进程中使用新的句柄/指针重新创建位图。COM组件作者处理的可能性很小,这样做并不容易,而且他肯定没有看到当时的要求,因为他认为该组件将始终在进程中使用。它已经不存在了。
对此没有简单的解决方法,您必须创建一个正确的代理/存根,并且至少需要访问组件的原始IDL。通常只有COM作者才能访问它。坏消息,我敢肯定。
一种可行的解决方法是将其留给.NET来处理它。您需要一个以32位模式运行的更小的辅助进程,因此可以毫无困难地加载COM组件。与其中一个.NET互操作机制(如WCF或Remoting)交谈。现在,将位图序列化完全掌握在您手中。