CoCreateInstance(转)

摘要:
创建组件的最简单方法是使用CoCreateInstance函数。COM库中包含用于创建组件的名为CoCreateInstance的函数。CoCreateInstance声明HRESULT_ stdcallCoCreateInstance;第一个参数:要创建的组件的CLSID。CoCreateInstance将在最后一个参数中返回指向此接口的指针。通过向CoCreateInstance传递IID,客户将不需要在创建组件后调用其QueryInterface函数。)如果在不支持DCOM_ REMOVE_的系统中设置CLSCTX,则SERVER值将被赋予CoCreateInstance,此函数将失败并返回E_ INVALIDARG值。

 

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_ALLCISCTX_SERVER中(在包含OBJEBASE.H之前定义_WIN32_DCOM的效果将是一样的。)若在某个不支持DCOM的系统中将CLSCTX_REMOVE_SERVER值会以给CoCreateInstance,此函数将会失败并返回一个E_INVALIDARG

   

   


CoCreateInstance
例子

跟之前的区别在于客户创建组件时使用的是::CoCreateInstance,还用了CoInitializeCoUninitialize来初始化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[])
{
    //
声明HRESULTIkuan接口指针
    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(转)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇tp5 中 model 的查询方法vSphere 高级特性FT配置与管理下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

AE 栅格数据使用总结

RasterBand)的数据组成,一个波段就是一个数据矩阵。对于格网数据(DEM数据)和单波段的影像数据,表现为仅仅只有一个波段数据的栅格数据集,而对于多光谱影像数据则表现为具有多个波段的栅格数据集。栅格编目(RasterCatalog)用于显示某个研究区域内各种相邻的栅格数据,这些相邻的栅格数据没有经过拼接处理合成一副大的影像图... 两个星期以来一直...

说说C#中IList与List区别

我知道IList是一个接口,而List可以实例化IList。请问,我不可以不定义接口IList么?或者在IDAL(接口中)定义List吗?必须是Ilist么??请大家谈谈他们之间的区别和作用? (摘自网络)   首先IList 泛型接口是 ICollection 泛型接口的子代,并且是所有泛型列表的基接口。 它仅仅是所有泛型类型的接口,并没有太多方...

yolo接口

在文件yolo_v2_class.hpp中声明。 extern "C" LIB_API int init(const char *configurationFilename, const char *weightsFilename, int gpu); extern "C" LIB_API int detect_image(const char *file...

java中为什么要实现序列化,什么时候实现序列化?

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,将数据分解成字节流,以便存储在文件中或在网络上传输。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。 序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implement...

spring cloud各个微服务之间如何相互调用(Feign、Feign带token访问服务接口)

1、首先先看什么是Feign。 这里引用“大漠知秋”的博文https://blog.csdn.net/wo18237095579/article/details/83343915 2、若其他服务的接口未做权限处理,参照上文第1点的博文即可。 3、若其他服务的接口做了权限的处理(例如OAuth 2)时该如何访问? a、有做权限处理的服务接口直接调用会造成调用...

说出一些常用的类,包,接口,请各举5个 ?

常用的包有: java.lang包下包括Math、System、StringBuilder、StringBuffer、Runtime、Thread、Runnable等。 java.util包下包括List、Set、Map,以及这些接口的常用实现类:ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等。...