fangyukuan永无止境的追求...追求卓越!!! |
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
评论
请问如何在win32 console application工程里创建com对象实例?我用CoCreateInstance函数总是报错。
你包含了objbase.h没了?如下:
#include <objbase.h>
你说的“报错”是指编译错误?还是CoCreateInstance返回码错误?
博主好
包含了objbase.h。
我想编OPC客户端程序,与西门子OPC服务器"OPC.SimaticNET"通讯。我写的相关的程序代码是:
#include <Objbase.h>
#include "Opccomn_i.c"
#include "OPCDA_I.C"
#include "OPCDA.H"
#include "OPCcomn.H"
#include "OPCError.h"
CLSID clsid;
IOPCServer *m_pIOPCServer;
CoInitialize(NULL);
r1=CLSIDFromProgID(L"OPC.SimaticNET",&clsid);
if(r1!= S_OK)
{
MessageBox(hMainWnd,"Retrival of CLSID failed",
"OPC.SimaticNET", MB_OK+MB_ICONEXCLAMATION);
CoUninitialize();
}
else MessageBox(hMainWnd,"Retrival of CLSID ok",
"OPC.SimaticNET", MB_OK+MB_ICONEXCLAMATION);
CoCreateInstance(clsid,NULL,CLSCTX_LOCAL_SERVER,
IID_IOPCServer,(void**)&m_pIOPCServer);
编译后报了两个错误,都是error C2115: 'function' : incompatible types,都指向CoCreateInstance。一个指向第一个参数clsid,另一个指向第四个参数IID_IOPCServer。
在未加CoCreateInstance时编译无错,运行后弹出对话框Retrival of CLSID ok。
warning C4024: 'CoCreateInstance' : different types for formal and actual parameter 1
warning C4024: 'CoCreateInstance' : different types for formal and actual parameter 4
从编译器给出的错误提示来看。是第一个和第四个参数,类型错误,你看一下,你的CoCreateInstance原型是不是这个:
WINOLEAPI CoCreateInstance(__in REFCLSID rclsid,
__in_opt LPUNKNOWN pUnkOuter,
__in DWORD dwClsContext,
__in REFIID riid,
__deref_out LPVOID FAR* ppv);
如果是,看一下。
#define REFCLSID const CLSID &
#define REFIID const IID &
看一下你的
clsid和IID_IOPCServer类型是不是跟 const CLSID和const IID一样。
我选中CoCreateInstance函数后,查看类型信息为:
long__cdecl CoCreateInstanceconst_GUID*,
IUnknown*,
unsigned long,
const_GUID*,
void**)
查看参数信息为:
HRESUL CoCreateInstance(REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
REFIID riid,
LPVOID * ppv)
我选中clsid后查看类型信息为:_GUID clsid,
选中IID_IOPCServer后查看类型信息,什么也没有。IID_IOPCServer是西门子公司提供的opc客户端程序中的参数。西门子公司的例子程序是用MFC编写的,这一句是从例子中照搬的,不知为什么出错。西门子opc服务器端程序我都安装了。
另外我在clsid和IID_IOPCServer之前各加一个&就不报错了,为什么。