在64位服务中使用32位DLL的指针 [英] Pointers using a 32 bit DLL in a 64 bit service

查看:101
本文介绍了在64位服务中使用32位DLL的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Until recently, we were running a service as x86, but changed it to Any CPU to use introduce some new functionality using a 64 bit DLL. One of the third party DLL's left over was 32 Bit. I setup a DLL surrogate for it in the registry, but that is only half the solution.

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

I suspect that the pointer being made in memory is not accessible because it's no longer run inProc. What I need to know is how do I use the System.Runtime.InteropServices.Marshall object to get access to the returned pointer.

谢谢.

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;
    }

推荐答案

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

Running in a surrogate is completely transparent to a properly implemented COM component. The proxy/stub for the component ensures that the arguments and return values of the interface methods are properly serialized by the proxy into an interop data packet so it can be transmitted across the process divide and deserialized again in the stub.

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

"Properly implemented" is however the rub. If you get a raw bitmap handle or pointer from a COM method then that sure spells trouble. A handle or pointer cannot be serialized, it is only valid in the process that created it. A custom proxy/stub is required that substitutes that handle with the actual bitmap data, transmits that data to the stub so the bitmap can to be recreated with a new handle/pointer in 64-bit process.

COM组件作者处理的可能性很小,这不容易做到,并且他肯定当时没有看到要求,因为他认为组件将始终在过程中使用.不再了.

The odds that the COM component author took care of that are small, it isn't easy to do and he surely didn't see the requirement at the time since he assumed the component would always be used in-process. It is not anymore.

对此没有简单的解决方法,您必须创建一个正确的代理/存根,并且至少需要具有该组件的原始IDL的访问权限.通常只有COM作者才能访问它.我确定是个坏消息.

There's no simple fix for this, you have to create a proper proxy/stub and that requires having at least access to the original IDL for the component. Usually only the COM author has access to that. Bad news, I'm sure.

一个可能的解决方法是将其留给.NET来处理.您将需要一个运行在32位模式下的辅助程序,以便可以轻松加载COM组件.与.NET互操作机制之一(例如WCF或Remoting)进行对话.现在,将位图序列化完全在您手中.

A possible workaround is to leave it up to .NET to take care of it. You'll need a littler helper process that runs in 32-bit mode so can load the COM component without trouble. Talk to it with one of the .NET interop mechanisms, like WCF or Remoting. Getting the bitmap serialized is now entirely in your hands.

这篇关于在64位服务中使用32位DLL的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆