com组件

C#编写COM组件

你。 提交于 2019-12-28 09:26:40
1、新建一个类库项目 2、将Class1.cs改为我们想要的名字 问是否同时给类改名,确定 3、修改Properties目录下面的AssemblyInfo.cs ComVisible属性设置为True 4、项目菜单->MyLib属性 找到“生成”选项卡 往下看,找到“为 COM Interop 注册”勾上 5、继续往下,找到“签名”选项卡 勾上“为程序集签名” 在下面的下拉框里面选择“ <新建...>” 6、在弹出的对话框里面,输入MyLib。。或者随便取个名字 去掉使用密码保护文件的选项 7、开始编码,任何一个公开的类,必须有一个 I开通的接口定义 using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace MyLib {   [ComVisible(true)]   [Guid("2CBD3D76-35F1-4f9d-9C1B-9DBFEE412F76")]   public interface IMyClass  {     void Initialize();     void Dispose();     int Add(int x, int y);   }   [ComVisible(true)]   

COM组件笔记

若如初见. 提交于 2019-12-25 13:12:52
HRESULT hr; S_OK:成功执行 S_FALSE:成功的返回逻辑错误 E_FAIL:一般性失败 E_NOTIMPL:方法没有实现 E_UNEXPECTED:在不准确的时间调用了方法 二、HRESULT分为三部分: 1、严重程度位:操作是成功还是失败 2、操作码:HRESULT对应于什么技术 3、信息码:在给定的严重程度和相应的技术情况下精确地结果值 为了消除名字冲突,所有的COM组件在设计的时候被分配为一个二进制名字GUID 当GUID被用来命名COM接口是,GUID被称为类ID (CLSID) 三、COM中不允许出现多继承 COM支持一种记号表示技术:“一个对象中哪些接口是可以使用的” queryInterface类似于static_cast() COM组件中所有的字符都用OLECHAR数据类型相当于win32中的w_char_t和16为的Unicode字符,BSTR以null作为结束符的OLECHAR字符串相当于string 当把字符串作为【in】参数传入一个方法是,最好调用方法之前使用SysAllocString,在调用方法之后调用SysFreeString 当把字符串作为【out】参数输出时最好使用SysAllocString,使用完参数之后SysFreeString交给调用者调用。(如果调用者不调用会照成内存泄露) variant变体的使用

微软的COM中GUID和UUID、CLSID、IID

最后都变了- 提交于 2019-12-18 19:23:10
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 当初微软设计com规范的时候,有两种选择来保证用户的设计的com组件可以全球唯一: 第一种是采用和Internet地址一样的管理方式,成立一个管理机构,用户如果想开发一个COM组件的时候需要向该机构提出申请,并交一定的费用。 第二种是发明一种算法,每次都能产生一个全球唯一的COM组件标识符。 第一种方法,用户使用起来太不方便,微软采用第 二种方法,并发明了一种算法,这种算法用GUID(Globally Unique Identifiers)来标识COM组件,GUID是一个128位长的数字,一般用16进制表示。算法的核心思想是结合机器的网卡、当地时间、一个随即 数来生成GUID。从理论上讲,如果一台机器每秒产生10000000个GUID,则可以保证(概率意义上)3240年不重复。 GUID的例子: 54BF6567--1007--11D1--B0AA--444553540000 HKEY_CLASSES_ROOT/CLSID/{002B9E07-2E10-438F-AF1E-40E6A96F1EE4} 在微软的COM中GUID和UUID、CLSID、IID是一回事,只不过各自代表的意义不同: UUID : 代表COM CLSID : 代表COM组件中的类 IID :代表COM组件中的接口 在程序中

软件工程简史

房东的猫 提交于 2019-12-18 05:21:48
从《WCF服务编程》一书中抄下来的,感觉对面向对象、面向组件和面向服务进行了很好的解释,但是对于我而言,需要反复看才能理解。 20世纪40-50年代,第一台通用的计算机才真正问世,它主要用于国防。这个时期的计算机可以运行代码并处理某些问题,而不仅仅是单个的预定义的任务。其缺点是计算机执行的代码与机器的硬件是紧密耦合的。实际上,当初计算机的软件与硬件之间并没有明显的区别(软件一词是在1958年才提出的)。起初,这个缺点并未引起大家的关注,因为世界上还没有手提电脑,都是超大型计算机。随着计算机产品大量生产,问题出现了。在20世纪60年代早期,汇编语言的出现才真正把机器与代码解耦开来,代码可以执行在不同的机器上。但是,代码与计算机的架构关联,即编写在8位机上的程序不能运行在16位机上,因为计算机的寄存器、可用内存和内存分布都不一样。因此,维护程序的成本逐渐增加。随着计算机的广泛应用,民众和政府部门为满足有限的资源与预算,提供了更好的解决方案。 20世纪60年代,更高级别的语言,如COBOL和FORTRAN,引入了编译器的概念。开发人员可以编写更加抽象的程序,编译器可以将其转化为实际的汇编代码。编译器第一次把代码从硬件和计算机架构解耦开来。第一代语言存在的问题是代码会导致非结构化的编程,这些代码通过使用jump或者go to语句依赖于它自身的结构

如何把DLL封装为COM组件供C++程序调用

时光总嘲笑我的痴心妄想 提交于 2019-12-09 04:13:19
需要将C#部分的接口提取出来,导出到COM,然后C++通过COM来调用它。 using System; using System.Runtime.InteropServices; namespace ClassLibrary1 { [ComVisible(true)] [Guid(“F3528A0F-D34F-4A5B-9849-0DCAD6212D5A”)] public interface MyInterface { int MyMethod(int param); } [Guid(“32B922E0-FED2-40CC-A9D6-57FE3EE341E3”)] public class Class1 : MyInterface { public int MyMethod(int param) { Console.WriteLine(“Class1.MyMethod is called!”); return param + 1; } } } 定义一个接口(待会儿C++调用对象上的方法要用),然后定义了一个类(待会儿C++创建对象要用),两个GUID一个标识接口的(在C++里QueryInterface的时候用)一个标识类的(在C++里CreateInstance的时候用)。GUID可以用VisualStudio自带的工具生成,也可以自己找在线生成的网站。

vs2010 用ATL创建com组件

*爱你&永不变心* 提交于 2019-12-07 11:09:52
使用vs2010创建ATL项目可以自动完成复杂的com组建编写 用ATL生成com组件的步骤: 1,新建一个ATL项目,选择dll,其他默认参数即可 2,在类视图中,右击项目,添加一个类,在向导中填写类的名称,如,testClass。注意参考注意事项的第一条。此时看到多了一个ItestClass的条目。 3,右击ItestClass条目,添加一个方法,如add,设置参数,勾选in表示输入,勾选out和retval表示外界调用时返回的参数(ATL中的函数实际的返回值都是S_OK) 4,在解决方案资源管理器中,右击testClass.cpp,在其中补全add函数即可 参考链接: http://www.cnblogs.com/xiaokang088/archive/2011/05/16/2047376.html 注意事项: 一:在添加类的时候,有个ProgID,如图,这个属性实际上必填的,但是在vs2008之前这个值都是自动填上的,但是在vs2010里这个值需要手动添加,否则生成的dll文件,虽然可以在vs2010中开发的程序中调用,但是在其他程序中如PHP中则会出错(如:PHP的“unable to create object,无效语法”,或者无法注册控件等)。ProgID的值可以参考,vs2008之前的形式:projectname.classname的形式命名。 二:

COM组件学习

北战南征 提交于 2019-12-07 10:04:58
COM组件是以Win32动态链接库(dll)或可执行的形式发布的可执行代码组成的。动态链接库本身并不能满足对于组件架构的需求。为了满足这些需求。组件还必须是封装的。 com组件是完全与语言无关的。 com组件可以以二进制形式发布。 com组件不妨碍老客户情况下升级。 com并不是一种计算机语言。 将com与dll相提并论也是不合适的。实际上com使用了Dll来给组件提供动态链接的能力。 com具有一个被称作是com库的API,他提供的是对所有客户及组件都非常有用的组件管理服务。 com组件在C++中是用纯抽象基类实现的。 一个com组件可以提供多个接口。 一个C++类可以使用多继承来实现一个可以提供多个接口的com。 客户请求服务时,只能通过接口进行。每一个接口都是有一个128位的全局唯一标识符GUID来标识 。客户通过GUID获得接口的指针,在通过接口指针,客户就可以调用其他相应的成员函数。具体功能如何实现,则完全由对象的接口内部实现。 每一个对象也用一个128位的GUID来标识,称为CLSID(类ID),客户程序可以由CLSID来创建COM对象。 接口特点: 1、二进制特性; 2、接口不变性; 3、继承性(可扩展性); 4、多态性(运行过程的多态性) COM定义的每一个接口都必须从IUnKnow继承过来。原因:IUnKnow接口提供了两个非常重要的特性: 生存期控制和接口查询

5.COM可重用性——包容

回眸只為那壹抹淺笑 提交于 2019-12-07 10:04:18
前面说的都是COM的模块化,体现COM组件的封装和多态特性,而实际上COM另一大特征是在二进制级别的可重用性,包括 包容和聚合 。本次介绍包容,下次介绍聚合。 如下,同样借用《COM原理与应用》的图,如下: 所谓 包容就是对象B在实现ISomInterface接口时,调用对象A的接口来完成这个功能 。换个角度看,其实相当于 对象B充当我们客户程序的角色 ,本来是要由B完成功能调用A来完成了,整个过程客户完全感觉不到对象A的存在,所以称作包容。 下面直接看代码实现,接着上篇博客的实现,以上文的实现的COM对象做A,本次实现新的对象B,包容对象A的IAge接口, 首先,在对象B中增加个初始化函数Init,查询得到对象A的IAge接口,如下 HRESULT CPeople::Init() { HRESULT hr = CoCreateInstance(CLSID_EasyComPeople, NULL, CLSCTX_INPROC_SERVER, IID_IAge, (LPVOID*)&m_pAge); if (FAILED(hr)) { return E_FAIL; } else { return S_OK; } } 然后,在对象B实现IAge接口功能的时候,调用对象A的IAge接口来完成这个功能, //IAge HRESULT STDMETHODCALLTYPE CPeople:

COM 包容组件

时间秒杀一切 提交于 2019-12-07 10:02:24
效果: <!--StartFragment --> 文件说明: 1、客户端 : CLIENT.cpp: main方法 Contain.exe :编译后的执行程序 GUIDS.CPP: GUID相关定义 IFACE.H:接口定义 2、组件: CMPNT1.cpp: 外部组件 CMPNT1.def: 接口定义 Cmpnt1.dll:编译后的DLL CMPNT2.cpp 内部组件 CMPNT2.def Cmpnt2.dll MAKEFILE :通过 nmake -f makefile 指令,将组件编译为DLL,并注册进入注册表 REGISTRY 相关文档 来源: CSDN 作者: jason5563 链接: https://blog.csdn.net/Jason5563/article/details/83611476

COM---组件复用:包容与聚合

余生长醉 提交于 2019-12-07 09:59:14
包容和 聚合为实现组件复用和定制提供了一种极鲁棒性的机制。使得COM框架下不需要实现继承,客户通组件的实现完全隔离开。 如果希望给组件增加新的接口,可以使用聚合。聚合是包容的一个特例。 以下代码只列出了关键部分,其它部分省略。 包容 外部组件包含指向内部组件接口的指针,此时外部组件只是内部组件的一个客户。外部组件可通过将调用转发给内部组件来重新实现内部组件的某个接口,还可在内部组件代码前后加上一些代码对接口改造。 组件1中的新成员m_pIY保存了指向所包容的组件2中IY接口的指针 外部组件 // // Component A // class CA : public IX, public IY //@N { public : // IUnknown virtual HRESULT __stdcall QueryInterface( const IID& iid, void ** ppv) ; virtual ULONG __stdcall AddRef() ; virtual ULONG __stdcall Release() ; // Interface IX virtual void __stdcall Fx() { cout << "Fx" << endl ;} // Interface IY virtual void __stdcall Fy() { m_pIY->Fy()