繁体   English   中英

C#中的COM客户端和服务器的InvalidCastException

[英]InvalidCastException with COM client and server in C#

我知道有关此主题的问题很多,但我相信我在过去10天内都经历了所有这些问题,但我找不到我所遭受的严重错误的解决方案。

我在C#中有一个COM服务器dll,在C#中有一个COM客户端。 Windows 7中的全部。我收到InvalidCastException,但无法解决问题。 我开始怀疑是否可以在C#中创建COM服务器。

我在实例化COM对象时遇到了该异常:

Test.MyImplementation mi = new Test.MyImplementation();

未处理System.InvalidCastException HResult = -2147467262消息=无法将类型为“ MyTest.MyImplementation”的对象强制转换为类型“ Test.MyImplementation”。 Source = ConsoleApplication3 StackTrace:位于c:\\ Users \\ rkohn \\ Documents \\ Visual Studio 2013 \\ Projects \\ ConsoleApplication3 \\ ConsoleApplication3 \\ Program.cs:ConsoleAppCOM.Program.Main(String [] args),位于System.AppDomain._nExecuteAssembly( RuntimeAssembly程序集,位于Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly(),位于System.Threading.ExecutionContext.RunInternal(ExecutionContext执行上下文,ContextCallback回调,对象状态,布尔状态,位于System.Threading.ExecutionContext.Run()处。在System.Threading.ExecutionContext.Run处的ExecutionContext executeContext,ContextCallback回调,对象状态,布尔值保持SyncCtx)在System.Threading.ThreadHelper.ThreadStart()处的ExecutionContext executeContext,ContextCallback回调,对象状态)InnerException:

这是COM服务器代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;


namespace MyTest
{

    [ComVisible(true)]
    [Guid("DBE0E8C4-DABA-41F3-B6A4-CAFE353D3D16")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IPimcManager
    {
        void GetTabletCount(out UInt32 count);
    }

    [ComVisible(true)]
    [Guid("C6659361-DABA-4746-931C-CAFE4B146690")]
    [ProgId("FakeServer.MyImplementation")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(IPimcManager))] //This to explicitly establish which is the default interface
    public class MyImplementation : IPimcManager
    {
        public MyImplementation() { }
        ~MyImplementation() { }
        public void GetTabletCount(out UInt32 count)
        {
            Console.WriteLine("GetTabletCount called!");
            count = 1;
        }
    }
}

这是客户端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace Test
{

    [ComImport]
    [Guid(PimcConstants.IPimcManagerIID)]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IPimcManager
    {
        void GetTabletCount(out UInt32 count);
    }

    [ComImport]
    [Guid(PimcConstants.PimcManagerCLSID)]
    class MyImplementation
    {
    }

    //        void GetTabletCount(out UInt32 count);
    //void GetTablet(UInt32 tablet, out IPimcTablet IPimcTablet);

    internal static class PimcConstants
    {
        //internal const string PimcManagerCLSID = "e23b1ced-5e47-4fdb-af66-b20370261b5e";
        internal const string PimcManagerCLSID = "C6659361-DABA-4746-931C-CAFE4B146690";
        internal const string IPimcManagerIID = "DBE0E8C4-DABA-41F3-B6A4-CAFE353D3D16";
        //internal const string PimcManagerCLSID = "c6659361-daba-4746-931c-cafe4b146690";
        //internal const string IPimcManagerIID = "dbe0e8c4-daba-41f3-b6a4-cafe353d3d16";
        //internal const string IPimcManagerIID = "af44bf80-36dd-4118-b4cf-8b1e3f4fb9ce";
    }

}

namespace ConsoleAppCOM
{

    class Program
    {

        [STAThread]
        static void Main(string[] args)
        {
            Test.MyImplementation mi = new Test.MyImplementation();
            Test.IPimcManager pimcManager = ((Test.IPimcManager)mi);


            uint cTablets = 0;
            pimcManager.GetTabletCount(out cTablets);

            System.Console.WriteLine(DateTime.Now + "-VALUE OBTAINED from PimcManager.GetTabletCount: " + cTablets);

            //Thread.Sleep(5);
            System.Console.ReadLine();
        }
    }

}

我已经尝试过STAThread,在服务器项目属性中选中了“为COM Interop注册”,并检查了客户端和服务器都针对x64 ...

我已经用C ++创建了一个COM Server,并且同一客户端可以与C ++ COM Server完美配合。 没有InvalidCastException。

这是从C#FakeServer的类型库获得的IDL:

// Generated .IDL file (by the OLE/COM Object Viewer)
// 
// typelib filename: FakeServer.tlb

[
  uuid(A3CFF4E2-8724-461F-AFD4-D74583E89513),
  version(1.0),
  custom(90883F05-3D28-11D2-8F17-00A0C9A6186D, "FakeServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

]
library FakeServer
{
    // TLib :     // TLib : mscorlib.dll : {BED7F4EA-1A96-11D2-8F08-00A0C9A6186D}
    importlib("mscorlib.tlb");
    // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
    importlib("stdole2.tlb");

    // Forward declare all types defined in this typelib
    interface IPimcManager;

    [
      odl,
      uuid(DBE0E8C4-DABA-41F3-B6A4-CAFE353D3D16),
      version(1.0),
      oleautomation,
      custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "MyTest.IPimcManager")    

    ]
    interface IPimcManager : IUnknown {
        HRESULT _stdcall GetTabletCount([out] unsigned long* count);
    };

    [
      uuid(C6659361-DABA-4746-931C-CAFE4B146690),
      version(1.0),
      custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "MyTest.MyImplementation")
    ]
    coclass MyImplementation {
        interface _Object;
        [default] interface IPimcManager;
    };
};

这是从C ++ COM Server的类型库中获得的IDL(请不要考虑添加到接口中的Name方法,我在测试中就这样做了):

// Generated .IDL file (by the OLE/COM Object Viewer)
// 
// typelib filename: simplecomserver.tlb

[
  uuid(6F818C55-E6AD-488B-9EB6-511C0CCC0612),
  version(1.0),
  custom(DE77BA64-517C-11D1-A2DA-0000F8773CE9, 134218331),
  custom(DE77BA63-517C-11D1-A2DA-0000F8773CE9, 1413900762),
  custom(DE77BA65-517C-11D1-A2DA-0000F8773CE9, "Created by MIDL version 8.00.0603 at Tue Oct 21 11:12:41 2014
")

]
library LibCOMServer
{
    // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
    importlib("stdole2.tlb");

    // Forward declare all types defined in this typelib
    interface ICOMServer;

    [
      odl,
      uuid(7F24AABF-C822-4C18-9432-21433208F4DC),
      oleautomation
    ]
    interface ICOMServer : IUnknown {
        HRESULT _stdcall Name([out, retval] BSTR* objectname);
        HRESULT _stdcall GetTabletCount([out] unsigned long* pcTablets);
    };

    [
      uuid(6AE24C34-1466-482E-9407-90B98798A712),
      helpstring("COMServer object")
    ]
    coclass CoCOMServer {
        [default] interface ICOMServer;
    };
};

与从接口_Object继承的C#协类是否有任何关系?

coclass MyImplementation {
    interface _Object;
    [default] interface IPimcManager;
};

任何帮助表示赞赏。

也许您的MyImplementation需要实现IPimcManager (就像在服务器代码中一样)。 尝试:

class MyImplementation : IPimcManager
{
    public void GetTabletCount(out UInt32 count)
    {
        // implement your code here
    }
}

希望这可以帮助。

请尝试以下操作:

在您的客户端类声明上,而不是

[ComImport]
[Guid(PimcConstants.PimcManagerCLSID)]
class MyImplementation
{
}

将其更改为接口并使用父接口GUID:

[ComImport]
[Guid(PimcConstants.IPimcManagerIID)]
interface MyImplementation:IPimcManager
    {
    }

希望能帮助到你

在.NET客户端中声明共同创建(可实例化)的COM类的通常模式不仅要求您声明类(例如下面的FooClass ),而且还需要类接口( Foo ),这是您将与new一起使用的接口( new Foo() )。 例如:

[ComImport]
[Guid(IIDs.IFoo)]  // IIDs.IFoo is a string constant containing the interface's IID
[CoClass(typeof(FooClass))]
public interface Foo : IFoo { }

[ComImport]
[Guid(CLSIDs.Foo)]  // CLSIDs.Foo is a string constant containing the co-class' CLSID
[ComDefaultInterface(typeof(IFoo))]
public class FooClass { }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM