CoCreateInstance

   

fangyukuan

永无止境的追求...追求卓越!!!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  93 随笔 :: 0 文章 :: 66 评论 :: 0 引用

公告

昵称: fangyukuan
园龄: 2年8个月
粉丝: 50
关注: 2

搜索

 

常用链接

我的标签

随笔分类(93)

随笔档案(93)

其它博客

学习伙伴

学习资源

积分与排名

  • 积分 - 40351
  • 排名 - 2971

最新评论

  • 1. Re:记事本1
  • 下载下来学习一下,暂不评价好坏。
  • --冬天tao
  • 2. Re:C/C++ 笔试、面试题目大汇总
  • @fangyukuan
    5. 将“引用”作为函数返回值类型的格式、好处和需要遵守的规则?

    (5)在另外的一些操作符中,却千万不能返回引用:+-*/ 四则运算符。它们不能返回引用
    (a+b)==(c+d) 的问题
  • --月光xia漫步
  • 3. Re:DDraw笔记-一个简单的DDraw应用程序
  • @china-Andy
    以前学ddraw是因为一个老游戏用到了ddraw,ddraw主要靠CPU,不能发挥显卡的优势,现在如果用DX,一般都会选择用D3D,你要学游戏开发,还是学D3D吧。现在做新游戏基本是不会用ddraw了。
  • --fangyukuan
  • 4. Re:C/C++ 笔试、面试题目大汇总
  • @月光xia漫步
    请问你说的是哪道?
  • --fangyukuan
  • 5. Re:C/C++ 笔试、面试题目大汇总
  • 上面你说的(a+b)==(c+d)恒为真,但是,我在自己的程序中,测试的不对啊!#include <iostream>using namespace std;void main(){ int a=1,b=2,c=3,d=4; if ((a+b)==(c+d)) { cout<<"a+b==c+d"<<endl; } else { cout<<"a+b!=c+d"<<en...
  • --月光xia漫步

阅读排行榜

评论排行榜

推荐排行榜

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,还用了CoInitializeCoUninitialize来初始化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/ATL
2
0
(请您对文章做出评价)
« 博主上一篇: COM笔记-COM库函数
» 博主下一篇: COM笔记-类厂
posted on  2010-06-11 23:34  fangyukuan 阅读(7082) 评论( 6编辑  收藏

评论

#1楼  2012-07-16 19:34  兔尾巴   
博主好!
请问如何在win32 console application工程里创建com对象实例?我用CoCreateInstance函数总是报错。
  

#2楼 [楼主] 2012-07-18 22:42  fangyukuan   
@兔尾巴
你包含了objbase.h没了?如下:
#include <objbase.h>

你说的“报错”是指编译错误?还是CoCreateInstance返回码错误?
  

#3楼  2012-07-19 09:54  兔尾巴   
@fangyukuan
博主好
包含了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。
  

#4楼  2012-07-19 10:07  兔尾巴   
同时还有两个警告:
warning C4024: 'CoCreateInstance' : different types for formal and actual parameter 1
warning C4024: 'CoCreateInstance' : different types for formal and actual parameter 4
  

#5楼 [楼主] 2012-07-19 23:58  fangyukuan   
@兔尾巴
从编译器给出的错误提示来看。是第一个和第四个参数,类型错误,你看一下,你的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一样。
  

#6楼  2012-10-07 17:40  兔尾巴   
博主好!
我选中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之前各加一个&就不报错了,为什么。
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值