CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

VC中怎么使用COM组件?

楼主wagnerwash()2002-02-26 14:14:25 在 VC/MFC / 基础类 提问

最好是能在Console   Application(without   MFC   support)中使用。  
  假如我有一个组件Com1.dll实现一个接口IMyCom1如下:  
  interface   IMyCom1   :   IDispatch  
  {  
          Func1();  
  };  
  怎么在程序中调用Com1.dll中IMyCom1的Func1()方法?  
  最好不要使用#import   "Com1.dll"   no_namespace的方法,因为这样必须在编译时指定使用的dll,岂不是还不如用一般的动态连接库,还能运行时LoadLibrary()? 问题点数:100、回复次数:31Top

1 楼wagnerwash()回复于 2002-02-26 14:16:07 得分 0

高手牛人,急急如律令!Top

2 楼flounder(一肩挑尽万古愁)回复于 2002-02-26 14:29:06 得分 5

你把接口在主框架中实例化,就可以了Top

3 楼finix(*_*)回复于 2002-02-26 14:44:41 得分 40

#incluide   "..\*.c"  
  #include   "..\*.h"  
  int   main(....)  
  {  
                      HRESULT   hr;  
                      IMyCom1     *pMyCom1=NULL;  
                      CoInitialize(NULL);  
                      hr=CoCreateInstance(  
                                    CLSID_MyCom1  
                                    NULL,  
                                    CLSCTX_INPROC_SERVER;  
                                    IID_IMyCom1,  
                                    (void**)&pMyCom1);  
              if(!SUCCEEDED(hr))  
              {  
                  .....  
              }  
        else  
            {  
                  pMyCom1->Func();  
                  pMyCom1->Release()  
                  pMyCom1=NULL;  
   
              }  
  CoUninitialize()  
  return   0;  
  }  
  或许对的  
  Top

4 楼wagnerwash()回复于 2002-02-26 15:52:08 得分 0

to   finix:  
  谢谢!  
  你的方法可行,但是怎么从Com1.dll生成Com1.h和Com1_i.c?  
  假如实现IMyCom1接口的组件要求运行时由用户指定(用户输入dll文件名或已注册的CLSID),又应该怎么做?Top

5 楼finix(*_*)回复于 2002-02-26 16:00:32 得分 0

由MIDL编译而成  
  #import智能指针Top

6 楼pazen()回复于 2002-02-26 16:07:26 得分 0

学习中Top

7 楼wagnerwash()回复于 2002-02-26 16:25:48 得分 0

to   finix:  
  MIDL是把idl文件编译成.h、.c文件,可是怎么从dll文件反编成.h、.c文件呢。  
  #import智能指针是什么意思?请大侠详细说说。Top

8 楼finix(*_*)回复于 2002-02-26 16:52:37 得分 5

#import智能指针生成的所有接口都以_com_ptr_t摸版为基础。  
  后者封装了IUnknown方法queryinterface(),addref(),release()和自己的函数  
  智能指针一般用于客户端,而原始接口用于服务器端,尽量不要混用,以免找成引用记数的错误导致内存泄露,崩溃。。。。Top

9 楼bskay() bskay() bskay()回复于 2002-02-26 16:53:10 得分 0

#import   d:\...\the.dll  
   
  就可以了Top

10 楼bskay() bskay() bskay()回复于 2002-02-26 16:54:44 得分 0

dll里面有关于如何产生.h(.tlh)   .c(.tli)信息的东东的Top

11 楼wagnerwash()回复于 2002-02-26 17:05:54 得分 0

能不能在运行时仅仅根据一个Dll的文件名或CLSID就搞定?生成.h、.c文件还是要在编译时进行。如果不能在运行时由用户指定实现IMyCom1的dll,用COM还不如用一般的dll导出函数呢。  
  finix大侠能不能给出一个像上面那样的例子?Top

12 楼kimryo(God is on my side)回复于 2002-02-26 17:14:53 得分 15

只用progid就行了,但麻烦很多。XXX.h和XXX_i.c是MIDL.exe编译.idl文件生成的,.tlb文件是二进制的用于在VB或java中的调用。所以你应该在另一个工程中包含XXX.h和XXX_i.c,这样可以直接用你的IMyCom1*   pMyCom=NULL;来定义指针、和使用接口ID:IID_IMyCom1常量等。你要示例工程我可以发给你。Top

13 楼idoloveyou(从高二开始上CSDN的人现在都工作了)回复于 2002-02-26 17:18:07 得分 5

你非要指定.dll文件名,又为什么非要用COM呢  
  直接LoadLibrary,然后GetProcAddress不久得了Top

14 楼wagnerwash()回复于 2002-02-26 17:34:35 得分 0

谢谢大家热情参与,我只能给100分,因此将在问题告一段落后给分。  
  有代码可以发到wagnerwash@sohu.comTop

15 楼wagnerwash()回复于 2002-02-26 17:38:27 得分 0

to   idoloveyou:  
  不一定是指定文件名,指定CLSID也可以。总之要在运行时确定。所以编译*.h、*_i.c的方法不行。  
  GetProcAddress()的方法详细的说来怎么做?是不是就是一般的dll导出函数?那样我也知道怎么做。之所以想用COM就是不想有“DLL地狱”的麻烦。Top

16 楼idoloveyou(从高二开始上CSDN的人现在都工作了)回复于 2002-02-26 21:31:15 得分 30

那你就不用那么麻烦了  
  你既然有IMyCom1的定义和组建的CLSID,那就可以得到IID_IMyCom1(查询注册表,可以从CLSID查到IID,观察一下注册表就可以了),就根本不需要#include什么*.h,   *.c的文件  
  直接CoCreateInstance(CLSID_Component,   NULL,   CLSCTX_ALL_SERVER,   IID_IMyCom1,   (void**)   &ppv)不就可以了吗Top

17 楼han012(阿毛)回复于 2002-02-27 09:10:24 得分 0

markTop

18 楼erlei1978(二雷)回复于 2002-02-27 13:04:44 得分 0

upTop

19 楼spdia(spdia)回复于 2002-02-27 13:12:21 得分 0

只要你实现的每个Com对象中都有IMyCom1接口,并且有IMyCom1的声明和IID_IMyCom1,就可以CoCreateInstance(CLSID_Component,   NULL,   CLSCTX_ALL_SERVER,   IID_IMyCom1,   (void**)   &ppv),#import需要dll中有类型库,他才能生成包裹类。Top

20 楼lostall(鸟人)回复于 2002-02-27 15:46:52 得分 0

#import   "progid:..."   no_namespace   named_guids  
  用progid,避免直接引入dll路径名。  
  具体可查MSDNTop

21 楼shuxh(shuxh)回复于 2002-02-27 17:27:01 得分 0

kimryo,    
  麻烦也给我一份例子程序,谢谢Top

22 楼shuxh(shuxh)回复于 2002-02-27 17:29:06 得分 0

kimryo,      
      麻烦也给我一份例子程序,谢谢  
      shuxh@163.net  
   
   
  Top

23 楼lgs(老臭虫)回复于 2002-02-27 17:29:46 得分 0

看看MSDN中使用ADO的例子就一切解决了!Top

24 楼shuxh(shuxh)回复于 2002-02-27 17:30:14 得分 0

kimryo,      
      麻烦也给我一份例子程序,谢谢  
      shuxh@163.net  
   
  Top

25 楼shuxh(shuxh)回复于 2002-02-27 17:31:25 得分 0

kimryo,      
      麻烦也给我一份例子程序,谢谢  
      shuxh@163.netTop

26 楼kevin_wang(砸锅卖铁)回复于 2002-02-27 20:44:48 得分 0

wang9658@263.netTop

27 楼tpProgramer(tp编程者)回复于 2002-02-28 08:44:45 得分 0

讨论的很热烈.  
   
    帮你们推.Top

28 楼luketang(Luke)回复于 2002-02-28 10:47:37 得分 0

不改了,自个凑合着看吧:  
  CLSID   clsid;  
  LPCLASSFACTORY   pClf;    
  LPUNKNOWN   pUnk;  
  HRESULT   hr;  
  IDispatch   *   pdisp;  
   
  //查找CLASS   ID  
  if   ((::CLSIDFromProgID(L"SecurityMarket.NewsCenter.1",   &clsid))   !=   NOERROR)  
  {  
  return;  
  }  
   
  //产生类工厂  
  if   ((::CoGetClassObject(clsid,   CLSCTX_SERVER,  
  NULL,   IID_IClassFactory,   (void   **)   &pClf))   !=   NOERROR)    
  {  
  return;  
  }  
   
  //创建IUnknown指针  
  pClf->CreateInstance(NULL,   IID_IUnknown,   (void**)   &pUnk);  
  hr   =   pUnk->QueryInterface(IID_IDispatch,   (void**)&pdisp);  
   
  WCHAR *pMethodName   =   L"NewsList";  
   
  DISPID   dispid;  
  DISPPARAMS   dispparams;  
  VARIANTARG   params[3];  
  VARIANT   result;  
  CString   ParamText;  
  EXCEPINFO   ExceptInfo;  
   
  //   Get   dispatch   ID   corrisponding   to   method   name.  
  hr   =   pdisp->GetIDsOfNames(IID_NULL,   &pMethodName,   1,   LOCALE_SYSTEM_DEFAULT,   &dispid);  
  if(FAILED(hr))  
  {  
  TRACE(_T("Cannot   get   dispatch   id   of   calc   method."),   hr);  
  return;  
  }  
   
  VariantInit(&params[0]);  
  params[0].vt   =   VT_I4;  
  params[0].intVal   =   1001;  
   
  VariantInit(&params[1]);  
  params[1].vt   =   VT_I4;  
  params[1].intVal   =   2;  
   
  VariantInit(&params[2]);  
  params[2].vt   =   VT_I4;  
  params[2].intVal   =   1;  
   
  //   Initialize   DISPPARAMS   structure.  
  dispparams.cArgs   =   3;  
  dispparams.cNamedArgs   =   0;  
  dispparams.rgdispidNamedArgs   =   NULL;  
  dispparams.rgvarg   =   params;  
   
  //   Prepare   result   variant.  
  VariantInit(&result);  
   
  //   Invoke   the   specified   method.  
  hr   =   pdisp->Invoke(dispid,   IID_NULL,   LOCALE_SYSTEM_DEFAULT,   DISPATCH_METHOD,   &dispparams,   &result,   &ExceptInfo,   NULL);  
  if(FAILED(hr))  
  {  
  TRACE(_T("Invoke   of   calc   method   failed."));  
  }  
  else  
  {  
   
  //   Convert   result   to   a   string.  
  VariantChangeType(&result,   &result,   0,   VT_BSTR);  
   
  //   Display   result.  
  //AfxMessageBox(CString(result.bstrVal));  
   
  *pCtxt   <<   _T(CString(result.bstrVal));  
  }  
   
  //   Clean   up   variants.  
  VariantClear(&result);  
  VariantClear(&params[0]);  
  VariantClear(&params[1]);  
  VariantClear(&params[2]);Top

29 楼luketang(Luke)回复于 2002-02-28 10:50:53 得分 0

传入"SecurityMarket.NewsCenter"就可以调用本地的COM了。  
   
  最近用了SOAP,很方便。  
   
  但不知怎么样最方便地调用其他机器的COM?(即DCOM)Top

30 楼Ashura(阿修罗)回复于 2002-02-28 12:46:14 得分 0

参与一把……Top

31 楼kissfire(kissfire)回复于 2002-02-28 17:48:40 得分 0

signTop

相关问题

  • 子组件 想使用 父组件的 事件 要怎么写?
  • vc中在工具箱中使用com组件(.ocx),怎么知道这些组件有什么方法可以操作?
  • 使用组件
  • 用vb写的dll组件在vc中如何使用?
  • 用ATL写的COM组件在VC里怎样使用?!
  • 使用VC编写的一个COM 组件,有一个函数要返回一个ADODB.RecordSet的实例,该怎么做啊?
  • vb中怎么调试vc做的com组件
  • vb中怎么调试vc做的com组件
  • VC下做了一个COM组件,在C#下怎么用啊
  • AdoConnection组件使用

关键词

  • .net
  • 指针
  • 组件
  • dll
  • 文件名
  • 文件
  • 接口
  • 编译
  • 函数
  • hr

得分解答快速导航

  • 帖主:wagnerwash
  • flounder
  • finix
  • finix
  • kimryo
  • idoloveyou
  • idoloveyou

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo