C# 中的 COM 服务器(在 x64 应用程序中使用 x86 DLL)

3
我想在我的x64 C#应用程序中使用x86 dll! 在论坛上,我读到使用COM对象可以帮助我实现这个目的!这是我的ComServerSample。它被编译为x86。
    [ComVisible(true)]
    public class MyComServer : IMyComSample
    {        
        private dahuaIp.fDisConnect dissconn;

        public void con(int lLoginID, StringBuilder pchDVRIP, int nDVRPort, int dwUser)
        {

        }

        public string GetString()
        {
            dissconn = new dahuaIp.fDisConnect(con);
            var zdsc = dahuaIp.CLIENT_Init(dissconn, 0);

            return zdsc.ToString();
        }
    }

    [ComVisible(true), Guid("DBE0E8C4-2222-41f3-B6A4-4E2F353D3D05")]
    public interface IMyComSample
    {
        string GetString();
    }

这是一个使用此组件服务器的测试应用程序。

Type CSI = Type.GetTypeFromProgID("ComServerSample.MyComServer");
var COMobj = Activator.CreateInstance(CSI);
MethodInfo method = CSI.GetMethod("GetString", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

var sdfc = method.Invoke(COMobj, null);

当测试应用程序是x86时,这两个应用程序都可以正常工作!但是当测试应用程序是x64时,会出现以下错误:

由于以下错误,无法为具有CLSID {7B9F9A71-8E1B-3470-8A79-EEB4DA9B25A4} 的组件获取COM类工厂: 80040154 类未注册 (来自HRESULT的异常:0x80040154(REGDB_E_CLASSNOTREG))。

如何解决这个问题?我需要在x64应用程序中使用我的x86 dll!


你是否已经使用 regsvr32 注册了 DLL 文件? - Alex
2
一个进程内不能混合使用不同位数的程序。64位进程无法加载32位DLL,反之亦然。那么你如何在它们之间传递指针/句柄呢? - Seva Alekseyev
你是否正在使用 out of process 的 COM 组件? - crashmstr
crashmstr,我的DLL必须作为EXE文件吗?而不是作为DLL? - joker_ruslan
1个回答

3
你遇到了“未注册类”错误,是因为你使用了错误版本的Regasm.exe来注册类库,或者是你让VS自动注册。你必须使用64位版本的Regasm,它在c:\windows\microsoft.net\framework64子目录中。
然而,这并不能解决你的真正问题,COM只能桥接进程外的COM服务器位数差异。.NET不直接支持创建它们,只有进程内服务器容易实现。这就是你得到的,但它仍然会失败,因为进程内服务器必须与EXE的位数匹配。
在.NET中获取一个进程外的COM服务器需要使用COM+并从ServicedComponent类派生。一个逐步说明的如何做的文章在这里
坦白说,这样做并没有带来更多的好处。你最好使用.NET Remoting或WCF允许你的64位进程与加载32位组件的32位主机进程通信。

有人能帮忙在.NET中编写Out-of-Process COM服务器吗?这需要使用COM+并从ServicedComponent类派生,因为我无法理解这个教程http://support.microsoft.com/kb/306296。 - joker_ruslan
不要这样做。我的最后一段已经非常明确了。 - Hans Passant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接