本文详细阐述如何用C#创建COM组件,并能用VC6.0等调用。

附:本文适用任何VS系列工具。

在用C#创建COM组件时,一定要记住以下几点:

1。所要导出的类必须为公有;

2。所有属性、方法也必须为公有;

3。要导出的属性、方法必须用接口方式;如果没有在接口中声明,即使该方法(属性)为公有,也不能正常导出到COM。但他们可以被别的.NET程序所使用;

4。所有的事件也必须用接口方式;

现在开始正题:

一、新建一个Visual C#工程(习惯这种叫法了,现在应该叫解决方案),

选择类型“类库”;就叫MyCom吧。

二、编写导出接口。

为了大家理解方便,仅以一加法操作举例。如下:

1
2
3
4
5
6
[Guid("154BD6A6-5AB8-4d7d-A343-0A68AB79470B")]
public interface MyCom_Interface
{
    [DispId(1)]
    int Add(int a, int b);

  

Guid为全局唯一标识,可以用VS2008的命令提示符中输入:用guidgen工具(系统自带)可以产生guid,在几个复选框选择最后一个Registry Format,点击New Guid,然后COPY就行了(以下如有guid的字符串,可用同样操作产生)

[DispId(1)]为函数的标识。如果有多个函数可相应的在函数前面加[DispId(2)], [DispId(3)]…

三、创建事件接口。

1
2
3
4
5
[Guid("D11FEA37-AC57-4d39-9522-E49C4F9826BB"), 
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface MyCom_Events
{

  

Guid同二,不多说

InterfaceType表示向COM公开的方式,这里选择为以调度的方式向COM公开。

四、 创建具体类:

1
2
3
4
5
6
7
8
9
10
[Guid("2E3C7BAD-1051-4622-9C4C-215182C6BF58"),
 ClassInterface(ClassInterfaceType.None),
 ComSourceInterfaces(typeof(MyCom_Events))]
public class Class1 : MyCom_Interface
{
    public int Add(int a, int b)
   {
       return a + b;
   }
}

  

至此,代码完毕。很简单吧。别急,后面来有常常被忽略的步骤,先把整体代码放在下面(注意引用InteropServices):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System; 
using System.Runtime.InteropServices; 
using System.Text; 
namespace MyCom 
{
    [Guid("154BD6A6-5AB8-4d7d-A343-0A68AB79470B")]
    public interface MyCom_Interface
   {
       [DispId(1)]
       int Add(int a, int b);
   }
 
    [Guid("D11FEA37-AC57-4d39-9522-E49C4F9826BB"),InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface MyCom_Events
   {
   }
 
    [Guid("2E3C7BAD-1051-4622-9C4C-215182C6BF58"), ClassInterface(ClassInterfaceType.None),ComSourceInterfaces(typeof(MyCom_Events))]
    public class Class1 : MyCom_Interface
   {
        public int Add(int a, int b)
       {
            return a + b;
       }
   }

  

五、大家都知道COM是需要注册的。注册时要加密钥文件.SNK。

自动生成:项目属性->签名(signing)->程序集签名(Sign the assembly)。选择创建,文件名为MyCom,密码项不勾选。生成后在AssemblyInfo.cs文件中添加了[assembly:AssemblyKeyFile("MyCom.snk")]

手动添加:这一部就是生成SNK文件。进入VS2008命令提示符。用命令:sn –k MyCom.snk回车。我的在E:\vs2008\vc下面就生成了一个(MyCom.snk)的文件。(你们可以根据自己的命令提示符所在的文件目录下去找)。然后把它COPY到你的工程根目录下。打开AssemblyInfo.cs。在里面加入[assembly:AssemblyKeyFile("MyCom.snk")]

六、设置项目为com

(1)项目属性->应用程序->程序集信息->选中“使程序集COM可见”(英文版 - Make assembly Com-Visible )。
(2)项目属性->生成->选中“为COM互操作注册”(英文版 - Register for COM interop)。

八、生成。

如果在Debug下有一个MyCom.tlb,那你就成功了(肯定还有MyCom.dll)要此tlb文件是为了在VC6.0里面测试。

九、在VC里面建一个MFC对话框程序(当然Console程序也一样,我为了看着方便)。建好后,把刚刚生成的MyCom.tlb拷到你的根目录下。

十、选在代码里加入#import "MyCom.tlb",然后编写核心测试代码:(我是在一个Button1按钮里面添加的),如下:

1
2
3
4
5
6
7
8
9
10
11
12
void CTestDlg::OnButton1()
{
    CoInitialize(NULL); //注意初始化
    MyCom::MyCom_InterfacePtr p(__uuidof(MyCom::Class1)); //创建智能指针
    MyCom::MyCom_Interface *s = p;
    int a = 3;
    int b = 6;
    int c = s->Add(a,b);
    CString str;
    str.Format("%d",c);
    MessageBox(str);
}

  

当弹出一个9,就说明你已经成功用C#创建COM组件了。

本文详细阐述如何用C#创建COM组件,并能用VC6.0等调用。的更多相关文章

  1. C#创建COM组件

    本文详细阐述如何用C#创建COM组件,并能用VC6.0等调用. 附:本文适用任何VS系列工具. 在用C#创建COM组件时,一定要记住以下几点: 1.所要导出的类必须为公有: 2.所有属性.方法也必须为 ...

  2. 如何用ATL创建ActiveX控件

    演示截图: 代码简介或代码解析: 如何用ATL创建ActiveX控件 实现了一个ActiveX控件,它在一个圆内部有个正多边形,当用户在多变形内部单击将会使多边形的边数在当前的基础上+1,在多变形外部 ...

  3. 开一个帖子,等有时间了写写如何用shapelib创建点线面等shp图层

    开一个帖子,等有时间了写写如何用shapelib创建点线面等shp图层  C#操作shapelib的实例 http://files.cnblogs.com/yuxuetaoxp/Shapelib--D ...

  4. Java 写一段字符到指定的文本文档中,如果该文本文档不存在,则创建该文本文档

    写一段字符到指定的文本文档中,如果该文本文档不存在,则创建该文本文档 import java.io.File; import java.io.FileNotFoundException; import ...

  5. 在 Mac OS 上创建并运行 ASP.NET Core 1.0 网站

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  6. HTML5 UI框架Kendo UI Web教程:创建自定义组件(三)

    Kendo UI Web包 含数百个创建HTML5 web app的必备元素,包括UI组件.数据源.验证.一个MVVM框架.主题.模板等.在前面的2篇文章<HTML5 Web app开发工具Ke ...

  7. 动态创建angular组件实现popup弹窗

    承接上文,本文将从一个基本的angular启动项目开始搭建一个具有基本功能.较通用.低耦合.可扩展的popup弹窗(脸红),主要分为以下几步: 基本项目结构搭建 弹窗服务 弹窗的引用对象 准备作为模板 ...

  8. What?VS2019创建新项目居然没有.NET Core3.0的模板?Bug?

    今天是个值得欢喜的日子,因为VS2019在今天正式发布了.作为微软粉,我已经用了一段时间的VS2019 RC版本了.但是,今天有很多小伙伴在我的<ASP.NET Core 3.0 上的gRPC服 ...

  9. RMAN详细教程(三):备份脚本的组件和注释

    RMAN详细教程(一):基本命令代码 RMAN详细教程(二):备份.检查.维护.恢复 RMAN详细教程(三):备份脚本的组件和注释 RMAN详细教程(四):备份脚本实战操作 一.基本组件: 1.Ser ...

随机推荐

  1. 题解 guP2421 【[NOI2002]荒岛野人】

    本题珂以转换成一个式子 即求Ci + Pi × x ≡ Cj + Pj × x (mod M) 的最小答案是否大于寿命最小值 以人数为最小值开始枚举山洞数,用扩展欧几里得计算最优答案是否大于寿命 若不 ...

  2. Luogu P2754 星际转移问题

    Luogu P2754 星际转移问题 思路 首先,对于地球能否到达月球的问题,考虑使用并查集维护. 对于每艘飞船能够到达的站点,放进一个集合里,若两艘飞船的集合有交集,那么就合并两个集合,最后只要地球 ...

  3. Ubuntu虚拟机基本环境搭建以及参数设置

    # 设置root账户密码 sudo passwd root # 修改源镜像(提高下载更新速度) sudo apt-get update pip install open-vm-tools pip in ...

  4. c语言:sprintf() 数字转字符赋值给数组

    //sprintf() //sprintf 最常见的应用之一是把整数打印到字符串中,所以,spritnf 在大多数场合可以替代itoa /* 缓冲区溢出 第一个参数的长度太短了,没的说,给个大点的地方 ...

  5. C语言:源代码兼容WINDOWS LINUX

    使用库函数之前,应该用#include引入对应的头文件.这种以#号开头的命令称为预处理命令.C语言源文件要经过编译.链接才能生成可执行程序:1) 编译(Compile)会将源文件(.c文件)转换为目标 ...

  6. 关于Xpath定位方法知道这些基本够用

    一.写在前面 之前写过一些关于元素定位的文章,但是感觉都是很碎片,现在想做个整合,便有了这篇文章. 二.xpath的定位方法 关于xpath定位方法,网上写的已经很成熟了,现已百度首页为例,如下图: ...

  7. python之数据驱动ddt操作(方法二)

    import unittestfrom ddt import ddt,unpack,datafrom selenium import webdriverfrom selenium.webdriver. ...

  8. WEB安全新玩法 [8] 阻止订单重复提交

    交易订单的重复提交虽然通常不会直接影响现金流和商品流,但依然会给网站运营方带来损害,如消耗系统资源.影响正常用户订单生成.制造恶意用户发起纠纷的机会等.倘若订单对象是虚拟商品,也有可能造成实际损失.订 ...

  9. Mysql数据量较大时分页查询优化

    据表 collect ( id, title ,info ,vtype) 就这4个字段,其中 title 用定长,info 用text, id 是主键,vtype是int,vtype是索引. 最后co ...

  10. Maven国内仓库

    由于国外的官方Maven仓库比较慢,所以寻找国内的代理仓库. 网上找了一些博客,内容都是一模一样,并且不贴代理官方的说明. 我在阿里云的Maven仓库找到了官方说明. 下面直接贴配置指南: 配置指南 ...