公开托管COM本地服务器-E_NOINTERFACE

公开托管COM本地服务器-E_NOINTERFACE,com,interop,localserver,Com,Interop,Localserver,我试图将一个用C#编写的本地服务器暴露给非托管代码以允许互操作!托管代码如下所示: [Guid("A0D470AF-0618-40E9-8297-8C63BAF3F1C3")] [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IMyLocalInterface { void LogToServer(strin

我试图将一个用C#编写的本地服务器暴露给非托管代码以允许互操作!托管代码如下所示:


    [Guid("A0D470AF-0618-40E9-8297-8C63BAF3F1C3")]
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IMyLocalInterface
    {
        void LogToServer(string message);
    }

    [Guid("9E9E5403-7993-49ED-BAFA-FD9A63A837E3")]
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class MyLocalClass : IMyLocalInterface
    {
        public MyLocalClass()
        {
            Console.WriteLine("Object created!");
        }

        public void LogToServer(string message)
        {
            Console.WriteLine("Log > " + message);
        }
    }

    class Program
    {
        [MTAThread]
        static void Main(string[] args)
        {
            var srv = new RegistrationServices();
            var cookie = srv.RegisterTypeForComClients(typeof(MyLocalClass), RegistrationClassContext.LocalServer | RegistrationClassContext.RemoteServer, RegistrationConnectionType.MultipleUse);

            Console.ReadLine();

            srv.UnregisterTypeForComClients(cookie);
        }
    }
我的非托管代码执行以下操作:


#import "ManagedLocServer.tlb" no_namespace raw_interfaces_only

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitializeEx(NULL, COINIT_MULTITHREADED);
    {
        IMyLocalInterfacePtr ptr;
        ptr.CreateInstance(__uuidof(MyLocalClass));

        ptr->LogToServer(L"Initializing...");

    }
    CoUninitialize();
    return 0;
}
调试后,我发现CoCreateInstance可以正常工作,这意味着“Object created”会打印到托管服务器控制台中。但是,该对象上的QueryInterface会因E_NOINTERFACE而失败。我有点困惑为什么会这样。注册有问题吗(我的CLSID只有LocalServer32条目)?这是我的托管代码中的问题吗?如果有人能给我一个提示就好了:)

问候
Joe

您正在使用进程外COM。这需要封送处理支持,要进行方法调用,需要序列化方法的参数。这通常是通过使用midl.exe从.idl文件生成的代码构建代理/存根DLL来完成的。或者使用与类型库一起工作的标准封送拆收器。两者都需要HKCR\Interface中的注册表项


因为COM找不到封送员,所以您得到了E_NOINTERFACE。如果您有一个.idl文件,但没有,那么解决这个问题很简单,因为服务器是在.NET中实现的。不知道如何解决这个问题,我从来没有试过让它起作用。一个遥远的可能性是CLR互操作层提供封送处理支持。但你肯定至少要使用ComInterfaceType.InterfaceIsDual。这只是一个猜测。如果我想让它工作,我会先从一个.idl开始。

也许他可以尝试使用
regasm/tlb
生成一个类型库,然后在注册表中注册该类型库,从而获得免费的自动编组?@sharp-我不知道,这个工具已经离开很长时间了。它以regtlibv12.exe的名称重新出现在.NET 4.0中,至少在我的计算机上是这样。根本没有文档,甚至没有/?救命啊,我不知道它是干什么的。我希望它会写入HKCR\TypeLib,但在HKCR\Interface中写入所需条目的可能性非常小,因为这可能会打乱现有的注册。