VS2017 C++调用C#生成的COM组件

  • C#生成COM组件:

VS2017 ——> 新建 ——> 项目 ——> Visual C# ——> 类库(.NET Framework)

*注意:如果选择 "类库(.NET Standard)" 后面可能无法选择 "为COM互操作注册",同时记住选择的.NET Framework的版本

示例:新建的工程名为 ComExample,重命名Class1.cs为ComTest.cs,添加 System.Runtime.InteropServices

1.添加外部调用接口,C++只能调用COM中的接口,无法直接调用类和函数

[Guid("7B25B7CE-2D31-47BE-9066-9E0B1FDA1F89")]
public interface ComTestInterface
{
    [DispId(1)]
    int comTestMul(int a, int b);
}

2.添加事件接口

[Guid("80C1DA98-0D57-42B3-B3F6-A496FB684B1C"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ComTestEvents
{

}

3.添加具体的类

[Guid("3AFE4870-5760-4144-8339-C8676D97174E"), 
 ClassInterface(ClassInterfaceType.None), 
 ComSourceInterfaces(typeof(ComTestEvents))]
public class ComTest : ComTestInterface
{
    public int comTestMul(int a, int b)
    {
        return a * b;
    }
}

4.生成注册时的秘钥

  VS2017 ——> 解决方案(ComExample) ——> 属性 ——> 签名 ——> 为程序集签名 ——> 新建 ——> 名称(ComExample)             ——> 取消选择"使用密码保护的秘钥文件" ——> 确定

 成功后会看到解决方案下多了一个snk文件

5.将项目设置为COM

  VS2017 ——> 解决方案(ComExample) ——> 属性 ——> 应用程序 ——> 选择"使程序集COM可见" ——> 确定

  VS2017 ——> 解决方案(ComExample) ——> 属性 ——> 生成 ——> 输出 ——> 选择"为COM互操作注册"

6.编译

  可能会出现错误:拒绝访问。请确保您正在以管理员身份运行应用程序 

解决方法:进入 "C:\Windows\System32" ——> 以管理员身份打开cmd ——> 进入"C:\Windows\Microsoft.NET\Framework\vxxx"

根据自己的情况进入相应的Framework目录下,我用到的是v4.0.30319,输入以下命令成功后即可看到成功注册的COM组件 。

RegAsm.exe Your_Project_Path\bin\Debug\ComExample.dll /tlb:ComExample.tlb /codebase

 

*Guid:全局唯一标识,VS2017 ——> 工具 ——> 创建GUID ——> 单选框(5) ——> 复制

全部代码:

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

namespace ComExample
{
    [Guid("7B25B7CE-2D31-47BE-9066-9E0B1FDA1F89")]
    public interface ComTestInterface
    {
        [DispId(1)]
        int comTestMul(int a, int b);
    }

    [Guid("80C1DA98-0D57-42B3-B3F6-A496FB684B1C"), 
     InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface ComTestEvents
    {

    }

    [Guid("3AFE4870-5760-4144-8339-C8676D97174E"),                                     
     ClassInterface(ClassInterfaceType.None),                                        
     ComSourceInterfaces(typeof(ComTestEvents))]
    public class ComTest : ComTestInterface
    {
        public int comTestMul(int a, int b)
        {
            return a * b;
        }
    }
}
  •  C++调用COM组件:

 VS2017 ——> 新建 ——> 项目 ——> Visual C++——> Windows控制台应用程序(程序名称为"TestComExample")

将C#生成的COM组件ComExample.tlb拷贝到该工程的目录下,C++示例程序如下

#include "pch.h"
#include 
#include 
#import "ComExample.tlb"
using namespace ComExample;

int main()
{
    CoInitialize(NULL);
    ComExample::ComTestInterfacePtr ptr(__uuidof(ComExample::ComTest));

    std::cout << "ComExample Test" << std::endl;
    std::cout << "Output: " << ptr->comTestMul(2, 3) << std::endl;  //调用COM组件的接口
    CoUninitialize();

    return 0;
}

 如果发现无法加入源文件"ComExample.tlb",解决方法如下:

VS2017 ——> 解决方案(TestComExample) ——> 属性 ——> C/C++ ——> 常规 ——> 附加包含目录 ——> 编辑 ——> 选择工程目录(ComExample.tlb刚刚拷贝到该工程目录下) ——> 确定

编译并运行,成功后最终可看到控制台窗口的正确输出:


欢迎讨论! 

你可能感兴趣的:(VS2017)