代码之家  ›  专栏  ›  技术社区  ›  Nick Bolton

为什么我的C#“hello world”COM客户端和服务器会抛出强制转换异常?

  •  2
  • Nick Bolton  · 技术社区  · 14 年前

    comclient comserver ),使用一些非常简单的代码:

    using System;
    using System.Reflection;
    using System.Runtime.InteropServices;
    
    namespace comserver
    {
      class Program
      {
        static void Main(string[] args)
        {
          RegisterComObject();
        }
    
        public static void RegisterComObject()
        {
          Assembly asm = Assembly.GetExecutingAssembly();
          RegistrationServices reg = new RegistrationServices();
          bool f = reg.RegisterAssembly(asm, AssemblyRegistrationFlags.SetCodeBase);
          Console.WriteLine("RegisterAssembly: {0}", f ? "ok" : "fail");
        }
      }
    
      [ComVisible(true)]
      [Guid("49752A5D-4CAD-495f-A220-07B60CDB6CE8")]
      interface IComServerDemo
      {
        void SayHello(string name);
      }
    
      [ComVisible(true)]
      [Guid("8FDB8319-6EC3-45b4-A384-1403D3993A07")]
      public class ComServerDemo : IComServerDemo
      {
        public void SayHello(string name)
        {
          Console.WriteLine("Hello {0}!", name);
        }
      }
    }
    

    通信客户端/程序.cs

    using System;
    using System.Runtime.InteropServices;
    
    namespace comclient
    {
      class Program
      {
        static void Main(string[] args)
        {
          ComServerDemo csdObj = new ComServerDemo();
          IComServerDemo csd = (IComServerDemo)csdObj;
          csd.SayHello("Bob");
        }
      }
    
      [ComImport, Guid("8FDB8319-6EC3-45b4-A384-1403D3993A07")]
      public class ComServerDemo
      {
      }
    
      [ComImport, Guid("49752A5D-4CAD-495f-A220-07B60CDB6CE8")]
      interface IComServerDemo
      {
        void SayHello(string name);
      }
    }
    

    当我跑的时候comserver.exe,它注册COM接口OK:

    寄存器程序集:确定

    类型的未处理异常

    附加信息:无法强制转换 'comserver.ComServerDemo'要键入

    你知道我为什么会有这个例外吗?这个 通信客户端 项目未引用 通信服务器 班级。另外,我正在尝试创建一个out-of-proc-COM服务器,但我有一种感觉,这可能不起作用-对此有什么想法吗?

    3 回复  |  直到 14 年前
        1
  •  2
  •   Hans Passant    14 年前

    您需要在.NET4.0中添加一个名为“类型等价”的功能。它允许两个不同的.NET类型在具有完全相同的GUID时被认为是等效的。此功能用于实现新的“嵌入互操作类型”功能,因此无需部署pia。

    the docs 对于[TypeIdentifier]属性。

        2
  •  1
  •   Community taleinat    7 年前

    您似乎没有任何与此部分代码相关的内容:

      ComServerDemo csdObj = new ComServerDemo();  
      IComServerDemo csd = (IComServerDemo)csdObj;  
    

    ComServerDemo : IComServerDemo ,但在客户中你没有这种关系。尝试此强制转换应失败,因为编译器将看不到连接。

    编辑:同意 @Hans Passant 在类型等价上,您已经重新定义了(re:undefined)关系,这样类型等价就不再有效了。

        3
  •  0
  •   James Curran    14 年前

    好吧,你没有向我们展示comclient,所以我只能猜测,但我假设你定义了一个类 ComServerDemo

    但相同的定义并不等同于同一类型。

    更新(现在您发布了comclient)

    试着把你的定义 & IComServerDemo 在你的 comclient 同学们,进入 comserver

    using System; 
    using System.Runtime.InteropServices; 
    
    namespace comclient 
    { 
      class Program 
      { 
        static void Main(string[] args) 
        { 
          ComServerDemo csdObj = new ComServerDemo(); 
          IComServerDemo csd = (IComServerDemo)csdObj; 
          csd.SayHello("Bob"); 
        } 
      } 
    }
    namespace comserver
    { 
      [ComImport, Guid("8FDB8319-6EC3-45b4-A384-1403D3993A07")] 
      public class ComServerDemo 
      { 
      } 
    
      [ComImport, Guid("49752A5D-4CAD-495f-A220-07B60CDB6CE8")] 
      interface IComServerDemo 
      { 
        void SayHello(string name); 
      } 
    }