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(punkonwnOuter, 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库。
#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完成之后,组件实际上已经建立好了。在建立好一个组件之后,想要控制将组件装载到内存中何处或检查客户是否有来创建该组件基本上已经不可能了。
CoCreateInstance(转)的更多相关文章
- CoCreateInstance调用返回代码0x80040154的一种解决方法
引言 前面的一篇博文中总结了开发Windows Thumbnail Handler的一些经验.在公司实际项目中,需要同时针对图片和视频实现缩略图.同时还要在图片和视频文件的顶部加上LOGO.像如下这样 ...
- CoCreateInstance调用COM接口伪流程
在编写组件程序时,经常会使用CoCreateInstance直接取COM组件的接口,非常方便,那CoCreateInstance到底干了些什么事呢?1.CoCreateInstance取COM组件的接 ...
- 关于CoCreateInstance的0x800401f0问题
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&g_pGr ...
- COM笔记-CoCreateInstance
CoCreateInstance 创建组件的最简单的方法是使用CoCreateInstance函数. 在COM库中包含一个用于创建组件的名为CoCreateInstance的函数.此函数需要一个CLS ...
- 连接opcserver时报错 connecting to OPC Server "****" CoCreateInstance 服务器运行失败
在普通windows系统连接OPCServer可能会报这样的错,排查很长时间,OPCServer跟Client都运行正常,点号录入也正常. 最后发现,其实是OPCServer 与OPCClient 权 ...
- 玩转Windows服务系列——给Windows服务添加COM接口
当我们运行一个Windows服务的时候,一般情况下,我们会选择以非窗口或者非控制台的方式运行,这样,它就只是一个后台程序,没有界面供我们进行交互. 那么当我们想与Windows服务进行实时交互的时候, ...
- COM 组件基础——GUID 和 接口
一.前言 书接上回,话说在 doc(Word) 复合文件中,已经解决了保存 xls(Excel) 数据的问题了.那么,接下来又要解决另一个问题:当 WORD 程序读取复合文件,遇到了 xls 数据的时 ...
- 不注册COM在Richedit中使OLE支持复制粘贴
正常情况下在Richedit中使用OLE,如果需要OLE支持复制粘贴,那么这个OLE对象必须是已经注册的COM对象. 注册COM很简单,关键问题在于注册时需要管理员权限,这样一来,如果希望APP做成绿 ...
- 【VC++技术杂谈004】使用微软TTS语音引擎实现文本朗读
本文主要介绍如何使用微软TTS语音引擎实现文本朗读,以及生成wav格式的声音文件. 1.语音引擎及语音库的安装 TTS(Text-To-Speech)是指文本语音的简称,即通过TTS引擎把文本转化为语 ...
随机推荐
- luogu P2439 [SDOI2005]阶梯教室设备利用
题目链接 luogu P2439 [SDOI2005]阶梯教室设备利用 题解 dp 代码 #include<vector> #include<cstdio> #include& ...
- 【20181103T2】图【结论+bfs最短路】
一眼最短路 --感觉是个结论啊 建超级源汇? 什么鬼 合并ab和cd? 不一样的吗 开始想的至少有一条路径是最短路 然后发现不对: 开始对着这个图瞎想 从B开始找A的最短路,然后把到B小于等于的边赋成 ...
- HTTP首部字段
HTTP首部由首部字段名和首部字段值组成,以逗号隔开.如果首部出现重复,有些浏览器优先处理第一个出现的首部,有些优先处理后者. 主要分为四大类 通用首部字段 请求首部字段 响应首部字段 实体首部字段 ...
- Mybatis框架Day01(上)
框架课程 1 课程计划 第一天: 1.mybatis的介绍 2.Mybatis的入门 a) 使用jdbc操作数据库存在的问题 b) Mybatis的架构 c) Mybatis的入门程序 3.Dao的开 ...
- bzoj 4237: 稻草人 -- CDQ分治
4237: 稻草人 Time Limit: 40 Sec Memory Limit: 256 MB Description JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行 ...
- C++ tuple类型
前言 最近在看C++ Primer的时候,对于对象移动一直不太懂,所以在查找各种资料,仔细研究代码后,打算写篇博客记录下来,果然还是不要得过且过,看见不懂的就查,弄懂为止最好了. 对象移动 很多时候都 ...
- HDU 5699 货物运输 二分
货物运输 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5699 Description 公元2222年,l国发生了一场战争. 小Y负责领导工人运输物 ...
- redis缓存穿透解决办法--排它锁
- JS数组与PHP数组的对比
一.分类与创建 1:JS的数组都是索引数组,数组是一种特殊的对象,创建数组的方式有两种 //方式一 var arr1 = ['关羽', '张飞', '赵云', '马超', '黄忠']; //方式二 v ...
- py2exe使用方法 (含一些调试技巧,如压缩email 类)(转)
一.简介 py2exe是一个将python脚本转换成windows上的可独立执行的可执行程序(*.exe)的工具,这样,你就可以不用装python而在windows系统上运行这个可执行程序. py2e ...