COM笔记-CoCreateInstance
CoCreateInstance
创建组件的最简单的方法是使用CoCreateInstance函数。
在COM库中包含一个用于创建组件的名为CoCreateInstance的函数。此函数需要一个CLSID参数,在此基础上创建相应组件的一个实例,并返回此组件的某个接口。
CoCreateInstance 的声明
HRESULT _stdcall CoCreateInstance(REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
REFIID riid,
LPVOID * ppv);
第一个参数:待创建组件的CLSID。
第二个参数:用于聚合组件。
第三个参数:dwClsContext的作用是限定所创建的组件的执行上下文。
第四个参数:iid为组件上待使用的接口的iid。
CoCreateInstance 将在最后一个参数中返回此接口的指针。通过将一个IID传给CoCreateInstance,客户将无需在创建组件之后去调用 其QueryInterface函数。
CoCreateInstance的实现
HRESULT CoCreateInstance(const CLSID& clsid,
IUnknown* punkonwnDuter,
DWORD dwClsContext,
const IID& iid,
void** ppv)
{
// Set the out paameter to NULL
*ppv = NULL;
// Create the class factory
// and get an IClassFactroy interface pointer.
IClassFactory* pIFactory = NULL;
HRESULT hr = CoGetClassObject(clsid,
dwClsContext,
NULL,
IID_IClassFactory,
(void**)&pIFactory);
if (SUCCEEDED(hr))
{
// create the component.
hr = pIFactory->CreateInstance(punkonwnDuter, iid, ppv);
pIFactory->Release()();
}
return hr;
}
CoCreateInstance的使用
// Create component.
IX *pIX = NULL;
HRESULT hr = ::CoCreateInstance(CLSID_Companent1,
NULL,
CLSCTX_INPROC_SERVER,
IID_IX,
(void **)&pIX);
if (SUCCEEDED(hr))
{
pIX->Fx();
pIX->Release();
}
CLSCTX_INPROC_SERVER值告诉CoCreateInstance只装载包含进程中服务器或DLL中的组件。
类上下文
CoCreateInstance的第三个参数dwClsContext可以控制所创建的组件是在与客户相同的进程中运行,还是在不同的进程中运行,或者是在另外一台机器上运行。
CLSCTX_INPROC_SERVER
客户希望创建在同一进程中运行的组件。为能够同客户在同一进程中运行,组件必须是在DLL中实现。
CLSCTX_INPROC_HANDLER
客户希望创建进程中处理器。一个进程中处理器实际上是一只实现了某个组件一部分的进程中组件。该组件的基体附录将由本地或远程服务器上的某个进程外组件实现。
SLSCTX_LOCAL_SERVER
客户希望创建一个在同一机器上的另外一个进程中运行的组件。本地服务器是由EXE实现的。
SLSCTX_REMOTE_SERVER
客户希望创建一个在远程机器上运行的组件。此标志需要分布式COM正常工作。
执行上下文标记的一些预定义组合 |
|
常量名称 |
值 |
CLSCTX_INPROC |
CLSCTX_INPROC_SERVER CLSCTX_INPROC_HANDLER |
CLSCTX_ALL |
CLSCTX_INPROC_SERVER CLSCTX_INPROC_HANDLER SLSCTX_LOCAL_SERVER SLSCTX_REMOTE_SERVER |
CLSCTX_SERVER |
CLSCTX_INPROC_SERVER SLSCTX_LOCAL_SERVER SLSCTX_REMOTE_SERVER |
另外要说明的是,CLSCTX_REMOTE_SERVER值只是在包含OBJEBASE.H之前将_WIN32_WINNT的值定义为大于或等于0x0400时才会被加到CLSCTX_ALL和CISCTX_SERVER中(在包含OBJEBASE.H之前定义_WIN32_DCOM的效果将是一样的。)若在某个不支持DCOM的系统中将CLSCTX_REMOVE_SERVER值会以给CoCreateInstance,此函数将会失败并返回一个E_INVALIDARG值。
CoCreateInstance例子
跟之前的区别在于客户创建组件时使用的是::CoCreateInstance,还用了CoInitialize和CoUninitialize来初始化COM库。
http://www.cnblogs.com/fangyukuan/archive/2010/04/09/1708651.html
#include "stdafx.h"
#include<iostream>
using namespace std;
#include "http://www.cnblogs.com/ATLComDemo/ATLComDemo/ATLComDemo_i.c"
#include "http://www.cnblogs.com/ATLComDemo/ATLComDemo/ATLComDemo_i.h"
int _tmain(int argc, _TCHAR* argv[])
{
//声明HRESULT和Ikuan接口指针
Ikuan * IkuanATL = NULL;
HRESULT hr = CoInitialize(NULL); //初始化COM
//使用SUCCEEDED宏并检查我们是否能得到一个接口指针
if(SUCCEEDED(hr))
{
hr = CoCreateInstance(CLSID_kuan,
NULL,
CLSCTX_INPROC_SERVER,
IID_Ikuan,
(void **)&IkuanATL);
//如果成功,则调用AddNumbers方法,否则显示相应的出错信息
if(SUCCEEDED(hr))
{
long ReturnValue;
IkuanATL->Add(8,9,&ReturnValue);
cout << "The answer for 8+9 is:" << ReturnValue << endl;
IkuanATL->Release();
}
else
{
cout << "CoCreateInstance Failed." << endl;
}
}
CoUninitialize();//释放COM
return 0;
}
CoCreateInstance的不灵活性
CoCreateInstance创建组件的过程是:传给它一个CLSID,然后创建相应的组件,并返回 指向所请求的接口指针。它没有给客户提供一种能够控制组件创建过程的方法。
当CoCreateInstance完成之后,组件实际上已经建立好了。在建立好一个组件之后,想要控制将组件装载到内存中何处或检查客户是否有来创建该组件基本上已经不可能了。
本文地址:http://www.cnblogs.com/fangyukuan/archive/2010/06/11/1756724.html
COM笔记-CoCreateInstance的更多相关文章
- COM笔记-类厂
CoCreateInstance实际上并没有直接创建COM组件 ,而是创建了一个被称作是类厂的组件.而所需的组件正是由些类厂创建的.类厂组件的唯一功能就创建其他的组件.创建组件的标准接口是IClass ...
- 一个简单的DDraw应用程序
阅读排行榜 1. C/C++ 笔试.面试题目大汇总(72915) 2. [STL]list基础(21718) 3. COM笔记-CoCreateInstance(14842) 4. C/C++ ...
- 【转】COM技术内幕(笔记)
COM技术内幕(笔记) COM--到底是什么?--COM标准的要点介绍,它被设计用来解决什么问题?基本元素的定义--COM术语以及这些术语的含义.使用和处理COM对象--如何创建.使用和销毁COM对象 ...
- delphi操作xml学习笔记 之一 入门必读
Delphi 对XML的支持---TXMLDocument类 Delphi7 支持对XML文档的操作,可以通过TXMLDocument类来实现对XML文档的读写.可以利用TXMLDocum ...
- git-简单流程(学习笔记)
这是阅读廖雪峰的官方网站的笔记,用于自己以后回看 1.进入项目文件夹 初始化一个Git仓库,使用git init命令. 添加文件到Git仓库,分两步: 第一步,使用命令git add <file ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- SQL Server技术内幕笔记合集
SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
随机推荐
- 如何搭建一个简易的 Web Terminal(一)
前言 在介绍本篇文章的时候,先说一下本篇文章的一些背景.笔者是基于公司的基础建设哆啦 A 梦(Doraemon)一些功能背景写的这篇文章,不了解.有兴趣的同学可以去 袋鼠云 的 github 下面了解 ...
- Java基础00-字符串14
1. API 1.1 API概述 2. String String常用类的常用方法 String字符串变量的创建: 声明: String 变量名; String str; 声明并初始化: Str ...
- [刘阳Java]_CSS鼠标悬停
小白在学习前端技术时候,一定会在刚开始的时候学习CSS2和CSS3的相关知识.这篇内容给大家介绍一个CSS鼠标悬停的效果.大家可以先看下面的效果图,然后我们在说一下实现的效果要求吧 上图效果非常简单和 ...
- MySQL用B+树(而不是B树)做索引的原因
众所周知,MySQL的索引使用了B+树的数据结构.那么为什么不用B树呢? 先看一下B树和B+树的区别. B树 维基百科对B树的定义为"在计算机科学中,B树(B-tree)是一种树状数据结构, ...
- 在Java中,负数的绝对值竟然不一定是正数!!!
绝对值是指一个数在数轴上所对应点到原点的距离,所以,在数学领域,正数的绝对值是这个数本身,负数的绝对值应该是他的相反数. 这几乎是每个人都知道的. 在Java中,想要获得有个数字的绝对值,可以使用ja ...
- RedHat7.4安装在个人电脑(笔记本)中安装遇到的问题总结
RedHat7.4安装在个人电脑(笔记本)中安装 以下纯属个人在安装过程中遇到问题的一些总结,如果有描述不恰当的地方,还请给予指出,欢迎大家评论和交流. 物理主机的配置: 硬件配置: 华硕A456U笔 ...
- 【原创】case、casez和casex谁是谁
在Verilog中case语句经常用于多分支表决的结构,case后的表达式会与各分支表达式"全等"那么对应的分支会被执行.其基本结构如下: case(expression) exp ...
- 使用hsdis-amd64.dll打印java的汇编文件
文件放在D:\DeveSOFTWARE\jdk1.8.0_45\jre\bin目录下 hsdis-amd64.dll 下载路径:https://github.com/atzhangsan/file_l ...
- 用 JavaScript 刷 LeetCode 的正确姿势【进阶】
之前写了篇文章 用JavaScript刷LeetCode的正确姿势,简单总结一些用 JavaScript 刷力扣的基本调试技巧.最近又刷了点题,总结了些数据结构和算法,希望能对各为 JSer 刷题提供 ...
- MySql查询上周(周一到周日)每天的日期!土方!
首先介绍一个函数:YEARWEEK(date[,mode]) 主要说明一下后面的可选参数mode,这个参数就是指定一周里面哪一天是第一天. 默认一周是从周日开始,这显然不太符合我们的要求.要指定每周从 ...