2013-10-10 86 views
0

直到最近,我们还是将x86服务作为服务运行,但将其更改为任何使用64位DLL的新功能。剩下的第三方DLL之一是32位。我在注册表中为它设置了一个DLL替代品,但这只是解决方案的一半。在64位服务中使用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; 
    } 

回答

2

在代理中运行对正确实施的COM组件完全透明。组件的代理/存根可确保接口方法的参数和返回值由代理正确序列化为互操作数据包,以便它可以在存根中再次进行分割和反序列化。

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

COM组件作者处理这个问题的几率很小,这并不容易,他当时也没有看到需求,因为他认为组件始终在进程中使用。现在不行了。

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

一种可能的解决方法是将其留给.NET来处理它。您将需要一个以32位模式运行的小型辅助程序进程,因此可以毫无困难地加载COM组件。使用.NET interop机制之一与之交谈,如WCF或Remoting。获取位图序列化现在完全掌握在你的手中。

+0

谢谢你的清晰简洁的解释。我已经到了必须将程序的功能分成两个服务的程度。 64位的主要功能,然后是一个小的32位的剩余功能。我们被困在那里直到供应商唤醒到64位计算。 – BigBadOwl