原文:http://www.codeproject.com/Articles/7859/Building-COM-Objects-in-C
Building COM Objects in C#.

Introduction

The topics covered in this article are:

  • Creating a simple COM object in C# (use the COM Interop property).
  • Accessing the COM from a VC++ client. (I have tested it with VC++6.0 and VC++ .NET). Client uses the TypeLibrary (.TLB file).

For the sake of simplicity and ease of use for the developers, testing this code, I have used the Northwinddatabase built into with the default installation of SQL Server database.

  • Modify the name of the SQL Server in the COM object to connect to your SQL Server.
  • Also, I have created a default user ID and password of scott / tiger to connect to the database. Either create this, or use an existing ID / password.

Part I: Creating a simple COM object in C#

COM objects are of the type ClassLibrary. The COM object generates a DLL file. To create a simple COM object from the VS Development Environment, select ....

Hide   Copy Code
New->Project->Visual C# Projects ->Class Library

Create a project named Database_COMObject.

Remember: Exposing the VC# objects to the COM world requires the following ...

  • The class must be public.
  • Properties, methods, and events must be public.
  • Properties and methods must be declared on the class interface.
  • Events must be declared in the event interface.

Other public members in the class that are not declared in these interfaces will not be visible to COM, but they will be visible to other .NET Framework objects. To expose properties and methods to COM, you must declare them on the class interface and mark them with a DispId attribute, and implement them in the class. The order the members are declared in the interface is the order used for the COM vtable. To expose events from your class, you must declare them on the events interface and mark them with a DispId attribute. The class should not implement this interface. The class implements the class interface (it can implement more than one interface, but the first implementation will be the default class interface). Implement the methods and properties exposed to COM here. They must be marked public and must match the declarations in the class interface. Also, declare the events raised by the class here. They must be marked public and must match the declarations in the events interface.

Every interface needs a GUID property set before the interface name. To generate the unique GUID, use theguidgen.exe utility and select the Registry Format.

Here is how the interface class looks like ...

Hide   Copy Code
[Guid("694C1820-04B6-4988-928F-FD858B95C880")]
public interface DBCOM_Interface
{[DispId(1)]void Init(string userid , string password);[DispId(2)]bool ExecuteSelectCommand(string selCommand);[DispId(3)]bool NextRow();[DispId(4)]void ExecuteNonSelectCommand(string insCommand);[DispId(5)]string GetColumnData(int pos);
}

For COM events ..

Hide   Copy Code
// // Events interface Database_COMObjectEvents
[Guid("47C976E0-C208-4740-AC42-41212D3C34F0"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface DBCOM_Events
{
}

For the actual class declaration:

Hide   Copy Code
[Guid("9E5E5FB2-219D-4ee7-AB27-E4DBED8E123E"),ClassInterface(ClassInterfaceType.None),ComSourceInterfaces(typeof(DBCOM_Events))]public class DBCOM_Class : DBCOM_Interface{

Note the following property set before the class:

Hide   Copy Code
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(DBCOM_Events))]

The ClassInterfaceType.None indicates that no class interface is generated for the class. If no interfaces are implemented explicitly, the class will only provide late bound access through IDispatch. Users are expected to expose functionality through interfaces that are explicitly implemented by the class. This is the recommended setting for ClassInterfaceAttribute.

The ComSourceInterfaces(typeof(DBCOM_Events))] identifies a list of interfaces that are exposed as COM event sources for the attributed class. For our example, we do not have any events exposed.

Here is the complete COM object source ..

Hide   Shrink    Copy Code
using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using System.Data.SqlClient;
using System.Windows.Forms ;namespace Database_COMObject
{[Guid("694C1820-04B6-4988-928F-FD858B95C880")]public interface DBCOM_Interface{[DispId(1)]void Init(string userid , string password);[DispId(2)]bool ExecuteSelectCommand(string selCommand);[DispId(3)]bool NextRow();[DispId(4)]void ExecuteNonSelectCommand(string insCommand);[DispId(5)]string GetColumnData(int pos);}// Events interface Database_COMObjectEvents
    [Guid("47C976E0-C208-4740-AC42-41212D3C34F0"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]public interface DBCOM_Events {}[Guid("9E5E5FB2-219D-4ee7-AB27-E4DBED8E123E"),ClassInterface(ClassInterfaceType.None),ComSourceInterfaces(typeof(DBCOM_Events))]public class DBCOM_Class : DBCOM_Interface{private SqlConnection myConnection = null ; SqlDataReader myReader = null ;public DBCOM_Class(){}public void Init(string userid , string password){try{string myConnectString = "user id="+userid+";password="+password+";Database=NorthWind;Server=SKYWALKER;Connect Timeout=30";myConnection = new SqlConnection(myConnectString);myConnection.Open();//MessageBox.Show("CONNECTED");
            }catch(Exception e){MessageBox.Show(e.Message);}}public bool ExecuteSelectCommand(string selCommand){if ( myReader != null ) myReader.Close() ;SqlCommand myCommand = new SqlCommand(selCommand);myCommand.Connection = myConnection;myCommand.ExecuteNonQuery();myReader = myCommand.ExecuteReader();return true ;}public bool NextRow(){if ( ! myReader.Read() ){myReader.Close();return false ;}return true ;}public string GetColumnData(int pos){Object obj = myReader.GetValue(pos);if ( obj == null ) return "" ;return obj.ToString() ;}public void ExecuteNonSelectCommand(string insCommand){SqlCommand myCommand = new SqlCommand(insCommand , myConnection);int retRows = myCommand.ExecuteNonQuery();}}
}

Before you build the COM object, we have to register the object for COM Interop. To do this, right click the project name in the Solution Explorer. Click Properties. Click Configuration ->Build. Expand the output section. Set the Register for COM Interop to true.

Indicate that your managed application will expose a COM object (a COM-callable wrapper) that allows a COM object to interact with your managed application.

In order for the COM object to be exposed, your class library assembly must also have a strong name. To create a strong name, use the utility SN.EXE.

Hide   Copy Code
sn -k Database_COM_Key.snk

Open the AssemblyInfo.cs and modify the line:

Hide   Copy Code
[assembly: AssemblyKeyFile("Database_COM_Key.snk")]

Build the object. The build also results into a type library that can be imported into your managed or unmanaged code.

Part II: Creating a Client using Visual C++ to access this COM Object

I have tested the COM object with the VC++ 6.0 and VC++ .NET environment. Create a simple project using the VC++ development environment. Import the type library using the #import directive. Create a Smart Pointer to the Interface.Execute, the exposed functions from the interface. Make sure to add the CoInitialize() call when the application loads.

Hide   Copy Code
CoInitialize(NULL);Database_COMObject::DBCOM_InterfacePtrp(__uuidof(Database_COMObject::DBCOM_Class));
db_com_ptr = p ;
db_com_ptr->Init("scott" , "tiger");

This code executes a SQL Command against the Customers table and returns the customer information for a given customer ID.

Hide   Copy Code
char cmd[1024];
sprintf(cmd , "SELECT COMPANYNAME , CONTACTNAME ,CONTACTTITLE , ADDRESS  FROM CUSTOMERS WHERE CUSTOMERID = '%s'" , m_id );
const char *p ;bool ret = db_com_ptr->ExecuteSelectCommand(cmd);if ( ! db_com_ptr->NextRow() ) return ;_bstr_t mData = db_com_ptr->GetColumnData(3);
p = mData ;
m_address    =    (CString)p ;

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Building COM Objects in C#相关推荐

  1. Part I 空气曲棍球 Chapter8(Building Simple Objects)

    我们的空气曲棍球项目已经捣鼓好久了,现在绘制出来的桌面也是呈现出了一个好视角并且配合纹理映射后看起来更好了:然而由于球棍只是一个点所以看起来并不像真正的球棍,你能想象下使用像一个点一样的球棍打球会是什 ...

  2. 【译文转帖】用C#写COM组件 Building COM Objects in C#

    说明: 我是一个C#程序员,但是有一次一个需求只能用C/C++去写,恰好需要读取的数据存放在DB(SQL CE v3)里面,而我又不会C/C++(关键是用OleDB访问DB,这个实在是繁琐),所以催生 ...

  3. javascript功能_功能性JavaScript简介

    javascript功能 Hey everybody! I've written a book called Discover Functional JavaScript, and it's now ...

  4. 自动售货机编程_Rosmaro中基于视觉自动机的编程简介

    自动售货机编程 by Łukasz Makuch 通过ŁukaszMakuch Rosmaro中基于视觉自动机的编程简介 (An introduction to visual automata-bas ...

  5. mongodb的备份与恢复

    为什么80%的码农都做不了架构师?>>>    mongodb提供了两个命令来备份(mongodump )和恢复(mongorestore )数据库. 1.备份(mongodump ...

  6. A Guide to Python's Magic Methods

    Book Source:[https://rszalski.github.io/magicmethods/] magic methods: 名称前后有双下划线的方法 构造函数和初始化 初始化类实例时, ...

  7. 【翻译】安卓新播放器EXOplayer介绍

    [翻译]安卓新播放器EXOplayer介绍 http://developer.android.com/guide/topics/media/exoplayer.html 前言: Playing vid ...

  8. install onnx_tensort

    添加链接描述 install onnx_tensort 这是一个将onnx 转换成tensort的小工具 和tensorrt 的内置工具类似tensorrt转onnx为engine的用法 你需要下载o ...

  9. 如何使用JavaScript中的工厂函数构建可靠的对象

    Discover Functional JavaScript was named one of the best new Functional Programming books by BookAut ...

最新文章

  1. apple id无法创建_我们如何使用Apple的学习框架来创建我们的第一个应用程序
  2. scrapy proxy and user_agent
  3. 如何在一分钟内搞定面试官?
  4. 工业以太网的冗余功能有哪些?
  5. web加减乘除法c#_C#的加减乘除的问题
  6. (转)Spring Boot(七):Mybatis 多数据源最简解决方案
  7. 卢伟冰曝Redmi K30 Pro搭载骁龙865,却惨遭交罚款
  8. 瀑布流布局的实现方式
  9. html5与css3基础教程课件,揭秘HTML5和CSS3教学幻灯片.ppt
  10. 什么是Adam/ReLU/YOLO?这里有一份深度学习(.ai)词典
  11. 微星主板不用DrMOS了?
  12. apache poi使用例_Apache POI使用详解
  13. Android 混淆总结
  14. spyder安装pyqt5
  15. 机器学习(非线性回归)
  16. 以下7种硬件测试的种类,不知道的赶紧收藏了!
  17. java中级程序员需要掌握的一些必备知识
  18. 顺时针打印矩阵(编程题讲解)
  19. Hack The Box——Remote
  20. spyder汉化方法

热门文章

  1. 一天搞定CSS: 浮动(float)及文档流--10
  2. 修改linux内核启动动画,Android 开机界面及Linux内核启动界面的修改(tiny6410)
  3. 进腾讯了!(实习面经分享)
  4. 杭电2062java实现
  5. 表格嵌套—JavaWeb学习之路Day1
  6. iphone11返回上一级手势怎么设置_苹果iphone12怎么关闭程序appp 怎么返回上一步
  7. 升级鸿蒙系统效果,鸿蒙系统初体验 全方位体验升级[多图]
  8. oracle error-1555,从另外一个角度看ORA-1555
  9. python演示验证图像叠加过程_Python叠加矩形框图层2种方法及效果代码实例
  10. css3边框线倾斜,使用CSS3倾斜边框的Div?