潘爱民 2003-10-10 http://www.icst.pku.edu.cn/CompCourse2003/ COM对象的实现(续) 潘爱民 2003-10-10 http://www.icst.pku.edu.cn/CompCourse2003/

Slides:



Advertisements
Similar presentations
酒店绩效考核攻略 一 业务流程再造 管理环节突破 利润急速倍增 专为您企业量身裁衣服务 突破导师 : 周忠亭副教授 北京大学管理案例研究 中心特聘餐饮讲师 北洋战略研究院研究员 北大时代光华高级讲师 中国十大餐饮管理讲师 中华酒店管理专家教授 教育部首批中国餐饮经理人 师资成员.
Advertisements

人力资源工作总结 行政部 人力资源部年度工作 一方面通过招聘管理、劳动合同管理、 入离职管理等,确保各项人事管理工作 的合法性、规范性. 另一方面通过建立员工培训计划,加强 企业文化的贯彻和渗透,提升员工的凝 聚力和归属感,提升员工的敬业度。
配樂:夢的序曲 ( 鋼琴 ) 雁蕩山因山頂有湖,蘆葦茂密,結草為湯,南歸秋雁多宿於此,故名雁蕩。始於 南北朝,興於唐,盛於宋,雁蕩山來晚了一步,未能在 “ 五岳 ” 中占得一席之地。 沒有金碧輝煌的涂飾,村野之山的雁蕩倒因此多了份瀟灑風神。
1. 法律學系助教群: 大學部助教 徐碧霜 行政助教 葉靜芳 研究所助教 阮博謙 台中 法政學院 1. 台北 法商學院 民國 50 年 中興大學合併法商學院法律系 民國 89 年 法商學院改制為台北大學.
单元二:面向对象程序设计 任务二:借书卡程序设计.
第一节 职业基础知识 第二节 社会需要剖析 第三节 用人单位认知
股指期货的风险及防范.
产学研项目财务管理若干问题 鲁春艳
《疯 娘》 --100个人看后99个人会落泪的故事 图文:网络
2015届就业指导课程教学大纲介绍.
四資二甲 第三週作業 物件導向程式設計.
Memory Pool ACM Yanqing Peng.
关注品德与生活课的 探究性学习和微课程的发展
2012年度人力资源部工作总结
设计模式可以帮助我们改善系统的设计,增强 系统的健壮性、可扩展性,为以后铺平道路。
主讲:江西财经职业学院傅文清 联系电话: 教学模式与课程教学设计 主讲:江西财经职业学院傅文清 联系电话:
22 第 课 增强自我保护的意识和能力.
在课题探索中成长 东风东路小学 王洁华 全国红领巾示范学校 广东省一级学校
关注女职工劳动保护,维护女职工合法权益 ——《女职工劳动保护特别规定》解读
执行《劳动合同法》中 应当注意的十大问题.
第二章 JAVA语言基础.
潘爱民 COM开发 潘爱民
内容提要 对象的生命周期 构造函数 析构函数 拷贝构造函数. 常宝宝 北京大学计算机科学与技术系
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
单片机原理与应用 C/C++在现代数字计算机上的实现.
·线性表的定义及ADT ·线性表的顺序存储结构 ·线性表的链接存储结构 · 单向循环链表 · 双链表、双向循环链表 · 一元多项式的加法
八. COM跨进程特性 进程外组件 列集 标准列集过程 总体结构 存根 代理 接口列集器 ORPC通道 标准列集的实现 自定义列集
哈夫曼编码.
第六章 继承性和派生类 胡昊 南京大学计算机系软件所.
基于 C# 的 .NET Framework 程序设计
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
程序设计期末复习 黎金宁
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
十四. 名字对象 概念 IMoniker接口 名字对象的创建 根据显示名创建名字对象 类名字对象的创建 其他名字对象的创建
第六章 编写客户端程序.
五 COM对象 接口及其接口方法的实现 注册表 类厂 COM组件与客户程序的交互过程 类厂的由来 类厂的定义与实现 类厂的创建
COM:moniker、UDT、control
C/C++/Java 哪些值不是头等程序对象
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
潘爱民 COM:可连接对象 & 结构化存储 潘爱民
第三章 C# 基础知识.
第7章 繼承/多型/介面 注意: 本投影片僅供本書上課教師使用,非經同意請勿上網轉載或供拷貝.
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
第三章 链表 单链表 循环链表 多项式及其相加 双向链表 稀疏矩阵.
劉崇汎 崑山科技大學 電腦與通訊系 DLL的建立與引用 劉崇汎 崑山科技大學 電腦與通訊系
常宝宝 北京大学计算机科学与技术系 数据结构(三) 常宝宝 北京大学计算机科学与技术系
第五章 递归与广义表 递归的概念 递归过程与递归工作栈 递归与回溯 广义表.
C#程序设计基础 $3 成员、变量和常量.
第10讲 构造函数和析构函数 构造函数 析构函数 This 指针.
C++复习2----类与对象.
2.3 平面与回转体表面相交 回转体截切的基本形式 截平面 截平面 截交线 截交线.
第四章 栈和队列 栈 ( Stack ) 队列 ( Queue ) 优先队列 (Priority Queue) 小结.
水利绿色发展问题与建议 姜文来 中国农业科学院农业资源与农业区划研究所.
Inheritance -II.
第三章 数据抽象.
字符串 (String) 字符串是 n (  0 ) 个字符的有限序列, 记作 S = “c1c2c3…cn” 其中,S 是串名字
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第二章 Java语法基础.
第7章 程序的结构 四、生存期与存储属性 五、extern关键字与外部连接属性 六、static关键字与内部连接属性.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
C++语言程序设计 C++语言程序设计 第八章 继承 C++语言程序设计.
第五章 序列埠通訊 並列與序列通訊簡介 認識序列埠 認識字元資料類型 字串資料類型 從序列埠監控視窗觀察變數 從Arduino接收序列資料
JAVA 程式設計與資料結構 第三章 物件的設計.
第2章 Java语言基础.
C++语言程序设计 C++语言程序设计 第十一章 异常处理 C++语言程序设计.
本节内容 在堆中创建对象 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第二章 Java基础语法 北京传智播客教育
Presentation transcript:

潘爱民 2003-10-10 http://www.icst.pku.edu.cn/CompCourse2003/ COM对象的实现(续) 潘爱民 2003-10-10 http://www.icst.pku.edu.cn/CompCourse2003/

复习 COM对象 IDL描述 对象的创建:类厂 位置透明 注册表 自注册的COM组件

回顾:客户创建对象过程 客户提供信息 过程: 位置透明性的实现 组件位置、clsid、iid、结果接口指针地址ppv 根据组件位置,LoadLibrary GetProcAddress,获取DllGetClassObject 用clsid和IID_IClassFactory获得类厂对象接口指针pFactory 用iid、ppv调用pFactory->CreateInstance 位置透明性的实现 利用注册表 在COM组件和客户之间引入中介

COM库 创建过程 COM库处于COM组件和客户中间 调用过程 对于进程内组件, COM库不再参与处理

COM对象创建过程 客户 组件 COM创建函数 COM库 DllGetClassObject 类厂对象接口指针

COM创建函数 COM库中三个用于创建组件的函数: CoCreateInstance CoCreateInstanceEx CoGetClassObject CoCreateInstance CoCreateInstanceEx

CoGetClassObject 创建一个类厂 HRESULT CoGetClassObject( const CLSID& clsid, DWORD dwClsContext, COSERVERINFO *pServerInfo, const IID& iid, (void **)ppv );

CoCreateInstance HRESULT CoCreateInstance( const CLSID& clsid, IUnknown *pUnknownOuter, DWORD dwClsContext, const IID& iid, (void **)ppv );

CoCreateInstance实现伪码 HRESULT CoCreateInstance(const CLSID& clsid, IUnknown *pUnknownOuter, DWORD dwClsContext, const IID& iid, void *ppv) { IClassFactory *pCF; HRESULT hr; hr = CoGetClassObject(clsid, dwClsContext, NULL, IID_IClassFactory, (void *)pCF); if (FAILED(hr)) return hr; hr = pCF->CreateInstance(pUnkOuter, iid, (void *)ppv); pCF->Release(); }

CoCreateInstanceEx HRESULT CoCreateInstanceEx( const CLSID& clsid, IUnknown *pUnknownOuter, DWORD dwClsContext, COSERVERINFO *pServerInfo, DWORD dwCount, MULTI_QI *rgMultiQI );

三个创建函数选用原则 如果客户创建远程对象或者希望一次获取对象的多个接口指针,则选用CoCreateInstanceEx函数; 如果客户希望获取类厂对象或者要调用类厂的某些成员函数,则选用CoGetClassObject函数; 在其他情况下,使用CoCreateInstance函数创建对象,这是最常用的方法。

创建过程示意图

类厂的实现 class CDictionaryFactory : public IClassFactory { protected: ULONG m_Ref; public: CDictionaryFactory (void); ~ CDictionaryFactory (void); //IUnknown members HRESULT QueryInterface(const IID& iid, void **ppv); ULONG AddRef(); ULONG Release(); //IClassFactory members HRESULT CreateInstance(IUnknown *, const IID& iid, void **ppv); HRESULT LockServer(BOOL); }; 类厂的实现

CreateInstance函数的实现 HRESULT CDictionaryFactory::CreateInstance(IUnknown *pUnknownOuter, const IID& iid, void **ppv) { CDictionary * pObj; HRESULT hr; *ppv=NULL; hr=E_OUTOFMEMORY; if (pUnknownOuter != NULL) return CLASS_E_NOAGGREGATION; pObj=new CDictionary(); if (pObj== NULL) return hr; //待续

CreateInstance函数的实现(续) //续上页 //Obtain the first interface pointer (which does an AddRef) hr=pObj->QueryInterface(iid, ppv); if (hr != S_OK) { g_DictionaryNumber --; delete pObj; } return hr;

DllGetClassObject的实现 extern "C" HRESULT __stdcall DllGetClassObject(const CLSID& clsid, const IID& iid, void **ppv) { if (clsid == CLSID_Dictionary ) { CDictionaryFactory *pFactory = new CDictionaryFactory; if (pFactory == NULL) { return E_OUTOFMEMORY ; } HRESULT result = pFactory->QueryInterface(iid, ppv); return result; } else { return CLASS_E_CLASSNOTAVAILABLE;

类厂对组件生存期的控制 组件引用计数不计类厂 IClassFactory::LockServer函数

COM库 COM库的初始化 COM库的内存管理 组件程序的装载和卸载 常用函数和HRESULT

COM库的组成 用于创建过程的SCM(Service Control Manager) 其他 rpcss.exe ole32.dll 管理server、组件等 ……

Service Control Manager COM库的组成(续) COM应用 (COM client) COM应用 (COM server) OLE32.DLL OLE32.DLL Service Control Manager RPCSS.EXE

COM库的初始化 基本的初始化函数: 初始化之前唯一可以调用的函数: 另一个初始化函数: COM库的终止函数: HRESULT CoInitialize(void *pReserved); 初始化之前唯一可以调用的函数: DWORD CoBuildVersion(); 另一个初始化函数: CoInitializeEx COM库的终止函数: void CoUninitialize(void);

有关CLSID和ProgID的COM函数 IsEqualGUID、IsEqualIID、IsEqualCLSID CLSIDFromProgID、ProgIDFromCLSID StringFromCLSID、CLSIDFromString StringFromIID、 IIDFromString StringFromGUID2 内存由调用者分配 注意:COM库函数的字符串使用OLECHAR类型

COM库的内存管理 COM库提供了内存管理器以及内存管理器的标准 HRESULT CoGetMalloc(DWORD dwMemContext, IMalloc **ppMalloc); class IMalloc : public IUnknown { void * Alloc(ULONG cb) = 0; void * Realloc( void * pv, ULONG cb) = 0; void Free(void* pv) = 0; ULONG GetSize( void * pv) = 0; int DidAlloc(void * pv) = 0; void HeapMinimize()= 0; };

COM库内存管理用法(一) DWORD length = MAX_LENGTH; IMalloc * pIMalloc; HRESULT hr; hr=CoGetMalloc(MEMCTX_TASK, &pIMalloc); if (hr != S_OK) // return failure psz=pIMalloc->Alloc(length); pIMalloc->Release(); if (NULL==psz) ...... pszText = psz;

COM库内存管理用法(二) 三个封装函数: void * CoTaskMemAlloc(ULONG cb); void CoTaskMemFree(void *pv); void CoTaskMemRealloc(void *pv, ULONG cb);

COM库内存管理用法(三) DWORD length = MAX_LENGTH; IMalloc * pIMalloc; HRESULT hr; psz=CoTaskMemAlloc (length); if (NULL==psz) // return failure ...... pszText = psz;

COM库内存管理用法(四) WCHAR *pwProgID; char pszProgID[128]; hResult = ::ProgIDFromCLSID(CLSID_Dictionary, &pwProgID); if (hResult != S_OK) { …… } wcstombs(pszProgID, pwProgID, 128) ; CoTaskMemFree(pwProgID);

组件程序的装载和卸载 进程内组件的装载 进程外组件的装载 进程内组件的卸载 进程外组件的卸载 DllGetClassObject “/Embedding”命令行参数 进程内组件的卸载 CoFreeUnusedLibraries 进程外组件的卸载 main或者WinMain函数退出

进程内组件的卸载 组件不能自己卸载 客户调用COM库函数CoFreeUnusedLibraries COM库调用DLL组件的引出函数 HRESULT DllCanUnloadNow(); 若DllCanUnloadNow返回S_OK,则同意卸载 若DllCanUnloadNow返回S_FALSE,则不同意卸载 DllCanUnloadNow实现:对象计数+锁计数

COM库中一些常用函数 初始化函数 GUID有关的函数 对象创建函数 内存管理函数

HRESULT数据结构 表达方法的操作结果,32位整数 类别码:反映了函数调用结果的基本情况 操作码:标识了结果操作来源

HRESULT 操作码 类别码 Win32 SDK的头文件WinError.h 00 - 表示函数调用成功 01 - 包含了一些信息 #define FACILITY_WINDOWS 8 #define FACILITY_STORAGE 3 #define FACILITY_RPC 1 #define FACILITY_SSPI 9 #define FACILITY_WIN32 7 #define FACILITY_CONTROL 10 #define FACILITY_NULL 0 #define FACILITY_INTERNET 12 #define FACILITY_ITF 4 #define FACILITY_DISPATCH 2 #define FACILITY_CERT 11 类别码 00 - 表示函数调用成功 01 - 包含了一些信息 10 - 警告 11 - 错误 Win32 SDK的头文件WinError.h

HRESULT(续) FormatMessage函数 SUCCEEDED和FAILED宏 常用定义

总结:实现一个进程内COM组件的步骤 定义必要的CLSID和IID 实现COM对象 实现类厂对象 通过QueryInterface暴露其接口 管理引用计数,注意对全局引用计数的维护 实现类厂对象 对象的引用计数不记在全局对象引用计数内 维护锁计数 实现DllGetClassObject、DllCanUnloadNow (可选)实现两个注册函数

进程内组件与客户的协作过程