none
C# 调用 C++创建的COM组件 出现 Error RRS feed

  • 问题

  • C# 调用 C++创建的COM组件 出现 Error

    如图:

    我的COM组建是mycom.dll

    我已经注册成功在C++调用COM组建的工程中顺利运行;

    但是在C#调用mycom.dll时添加不了COM组建

    请问是什么原因呢?怎么做才能正确调用我创建的COM组建呢?

    

    2014年2月18日 5:46

答案

  • 谢谢 DroidXgnaW 大神你的热心帮助我已经很开心了,在论坛还是有很多人愿意分享

    现在好像还有一种调用COM组件的方式我在研究:

    我尝试编写了下代码

    如下述代码:

        [ComImport, Guid("85F5CF11-2A25-4ef9-8F7C-8C3F14A0860A")]
        class FilgraphManager 
        { 
    
    
        }
    
        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("07C4A7BC-BBD1-4ced-80A5-A76377929F35")]
        public interface IIncr
        {
           void Add([In] int nOp1, [In] int nOp2, ref int pret);
        }  
    
        class Program
        {
            static void Main(string[] args)
            {
                FilgraphManager g = new FilgraphManager();
                IIncr i = (IIncr)g;
                int t = 90;
                i.Add(1,2,ref t);
                Console.WriteLine("t is " + t);
            }
        }

    可是还是有错误,我想我还没理解的足够好,ComImport和组件的CLSID

    来调用组件的接口方法

    我还在尝试,希望我能慢慢进步,

    真的非常感谢你!

    http://www.qingfengju.com/article.asp?id=84

    你是按照这种方式来建立的 COM 项目吧!

    • 已标记为答案 Wayne1900 2014年2月19日 3:11
    2014年2月19日 3:05

全部回复

  • 代码在我skydrive的共享文件夹下文件名称是:“CSharpCallCOM”

    https://skydrive.live.com/?cid=d2327ea047e691b7#cid=D2327EA047E691B7&id=D2327EA047E691B7%21105

    • 已编辑 Wayne1900 2014年2月18日 5:50 修改
    2014年2月18日 5:49
  • 这个步骤应该不难,可刚入门,一直未很好的掌握,希望,各位能帮助我成功调用这个COM组件
    2014年2月18日 8:25
  • 从 COM 选项卡中找到后添加。

    2014年2月18日 8:40
  • COM选项卡中看见不到mycom
    2014年2月18日 8:42
  • 我也尝试过从COM选项卡中找到mycom.dll然后添加可是直接就会报错误
    2014年2月18日 8:45
  • 我也尝试过从COM选项卡中找到mycom.dll然后添加可是直接就会报错误

    http://www.soaspx.com/dotnet/csharp/csharp_20100511_4287.html

    有个 ProgId,从 COM 选项卡中可以找到。

    出现什么错误?

    2014年2月18日 9:01
  • 我注册成功了,管理员全新注册了mycom.dll

    在C++调用COM组建成功

    可是在C#这边调用COM组建,我在COM选项中无法找到?

    麻烦能否截图下,你在COM选项卡中找到注册的com组建截图吗?感谢!!!

    2014年2月18日 9:08
  • 我就是在COM->类型库下 找不到注册的COM组建 

    2014年2月18日 9:10
  • 死活找不到、、、
    2014年2月18日 9:15
  • 1、你用 IID_ITest 的值去注册表里搜索出你的 mycom.dll 的 ProgID。

    2、在 COM 类型库中,你也可以通过注册组建的物理路径来找到。

    2014年2月18日 9:45
  • 我在注册表按照CLSID找到了ProgID

    可是在COM组件还是看不到

    如图:

    2014年2月19日 0:59
  • 抱歉,麻烦请问各位能在COM 引用里找到了么?

    2014年2月19日 1:03
  • 我确定我注册成功已经,如图:

    2014年2月19日 1:06
  • 我尽可能详细的叙述两种添加 COM 组件引用的方式:

    1、在添加引用的对话框中直接选择 mycom.dll 文件。

    我假设你的 mycom.dll 的全路径为 D:\ComTest\mycom.dll,在命令行(管理员权限启动)输入并回车:

    regsvr32.exe /i D:\ComTest\mycom.dll

    在添加引用的对话框中,选择“浏览”,然后找到 D:\ComTest\mycom.dll 文件,选中,并点击确定。

    这里的要点就是,你注册的 COM 组件的路径(在注册表中通过 InprocServer32 键值查看)同你引用的 COM 组件的路径要一致。

    2、在添加引用的对话框中通过 COM 类型库选择。

    在 COM 选项框中显示的名称为 COM 组建的类型库的名称,我假设你的 COM 组件是通过 ATL 的方式建立,那么在 .idl 文件中,找到你的类型库定义,它的结构应该如下:

    [
     object,
     uuid(16299BDF-F3B3-4A82-815C-A71E37512411),
     dual,
     nonextensible,
     helpstring("Imycomxxxxx Interface"),
     pointer_default(unique)
    ]
    interface Imycomxxxxx : IDispatch{

    // 方法省略。

    };

    [
     uuid(AEEFDC84-3E26-4313-B803-546B3954BD30),
     version(1.0),
     helpstring("mycom 1.0 Type Library")   // 这里设置的字符串就是显式在 COM 选项框中的名称。
    ]
    library mycomLib
    {
     importlib("stdole2.tlb");

     // 接口、事件省略

    };

    2014年2月19日 1:43
  • 首先我尝试了DroidXgnaW您的命令注册,regsvr32 /i D:\ComTest\mycom.dll

    可是出现错误:

    如图:




    2014年2月19日 2:22
  • 我输入 regsvr32 D:\ComTest\mycom.dll 命令就能注册成功:

    2014年2月19日 2:23
  • 然后我去直接添加mycom.dll 还是有如下的错误:

    我添加的mycom.dll就是D:\ComTest\mycom.dll目录下的COM组件的DLL

    如图:

    2014年2月19日 2:25
  • 对于第二种方式:

    我的COM组件不是通过ATL方式建立,没有下述的SourceCode

    [
     uuid(AEEFDC84-3E26-4313-B803-546B3954BD30),
     version(1.0),
     helpstring("mycom 1.0 Type Library")   // 这里设置的字符串就是显式在 COM 选项框中的名称。
    ]
    library mycomLib
    {
     importlib("stdole2.tlb");

     // 接口、事件省略

    };

    Sorry,这无法进行有效的参考


    2014年2月19日 2:28
  • All-In-One Code Framework 中有个示例项目 ATLDllCOMServer,你按照这个项目把你的 mycom.dll 修改下。

    2014年2月19日 2:30
  • 对于第二种方式:

    我的COM组件不是通过ATL方式建立,没有下述的SourceCode

    [
     uuid(AEEFDC84-3E26-4313-B803-546B3954BD30),
     version(1.0),
     helpstring("mycom 1.0 Type Library")   // 这里设置的字符串就是显式在 COM 选项框中的名称。
    ]
    library mycomLib
    {
     importlib("stdole2.tlb");

     // 接口、事件省略

    };

    Sorry,这无法进行有效的参考


    MFC 编写 COM 组件,它也有 .idl 文件。

    难道都不是?你没用任何框架,纯手工编写的?

    2014年2月19日 2:34
  • 对的,我都是自己纯手工写的,因为我入门所以我根据教程自己完全手工创建了COM组件

    在我的Debug目录下没有。idl文件,如图:

    我一直无法C#调用COM组件成功,如上面的错误,显示可能是无效的COM组件;

    可是我在我的C++工程里能成功调用这个COM组件的啊?

    我不理解了

    2014年2月19日 2:42
  • 我完全手工实现的COM组件,因为如此所以在我的COM组件选项卡里无法找到?

    可是明明这个COM组件是正确的,难道没有使用框架[没有.idl文件]就无法添加这COM组件引用在C#的工程中?

    2014年2月19日 2:45
  • 就会产生如图的错误信息吗?

    2014年2月19日 2:46
  • 对的,我都是自己纯手工写的,因为我入门所以我根据教程自己完全手工创建了COM组件

    在我的Debug目录下没有。idl文件,如图:

    我一直无法C#调用COM组件成功,如上面的错误,显示可能是无效的COM组件;

    可是我在我的C++工程里能成功调用这个COM组件的啊?

    我不理解了

    .idl 文件在源代码中,不在输出目录。

    你的问题是没有正确的 Type library 。

    没有 Type library 的情况下,在 C# 中,你也可以通过 DllImport CoCreateInstance 而不是通过引用来调用 COM 组件。

    我的水平不够,还没有办法不依赖 MFC 或 ATL 来独立创建 COM 项目。所以如果你不将项目切换到 MFC 或 ATL 上来的话,我恐怕无法帮你解决问题。

    2014年2月19日 2:53
  • 谢谢 DroidXgnaW 大神你的热心帮助我已经很开心了,在论坛还是有很多人愿意分享

    现在好像还有一种调用COM组件的方式我在研究:

    我尝试编写了下代码

    如下述代码:

        [ComImport, Guid("85F5CF11-2A25-4ef9-8F7C-8C3F14A0860A")]
        class FilgraphManager 
        { 
    
    
        }
    
        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("07C4A7BC-BBD1-4ced-80A5-A76377929F35")]
        public interface IIncr
        {
           void Add([In] int nOp1, [In] int nOp2, ref int pret);
        }  
    
        class Program
        {
            static void Main(string[] args)
            {
                FilgraphManager g = new FilgraphManager();
                IIncr i = (IIncr)g;
                int t = 90;
                i.Add(1,2,ref t);
                Console.WriteLine("t is " + t);
            }
        }

    可是还是有错误,我想我还没理解的足够好,ComImport和组件的CLSID

    来调用组件的接口方法

    我还在尝试,希望我能慢慢进步,

    真的非常感谢你!

    2014年2月19日 2:59
  • 谢谢 DroidXgnaW 大神你的热心帮助我已经很开心了,在论坛还是有很多人愿意分享

    现在好像还有一种调用COM组件的方式我在研究:

    我尝试编写了下代码

    如下述代码:

        [ComImport, Guid("85F5CF11-2A25-4ef9-8F7C-8C3F14A0860A")]
        class FilgraphManager 
        { 
    
    
        }
    
        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("07C4A7BC-BBD1-4ced-80A5-A76377929F35")]
        public interface IIncr
        {
           void Add([In] int nOp1, [In] int nOp2, ref int pret);
        }  
    
        class Program
        {
            static void Main(string[] args)
            {
                FilgraphManager g = new FilgraphManager();
                IIncr i = (IIncr)g;
                int t = 90;
                i.Add(1,2,ref t);
                Console.WriteLine("t is " + t);
            }
        }

    可是还是有错误,我想我还没理解的足够好,ComImport和组件的CLSID

    来调用组件的接口方法

    我还在尝试,希望我能慢慢进步,

    真的非常感谢你!

    http://www.qingfengju.com/article.asp?id=84

    你是按照这种方式来建立的 COM 项目吧!

    • 已标记为答案 Wayne1900 2014年2月19日 3:11
    2014年2月19日 3:05
  • 对的,我的实现就是按照上述的方式实现的,可以去我的源码看,完全就是这种方式所以没有.tlb文件
    2014年2月19日 4:38
  • 对的,我的实现就是按照上述的方式实现的,可以去我的源码看,完全就是这种方式所以没有.tlb文件

    http://www.qingfengju.com/article.asp?id=84

    我已经给出链接了,里面最后一句话已经说了:这样实现的COM组件没有类型库(.tlb文件)。

    你可以手动添加 IDL 了文件:
    http://blog.sina.com.cn/s/blog_53a14a750100gsdx.html

    2014年2月19日 6:03