CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  ATL/ActiveX/COM

在COM组件中,怎样把自定义的结构体作为,其接口方法的参数呢?

楼主ISAKEEPER()2003-09-04 20:32:44 在 VC/MFC / ATL/ActiveX/COM 提问

我是用MFC写的组件,DATA是我在.H中定义的一个结构,我要把SendList(DATA   &data,DWORD   n)变成COM接口方法,应该怎样做呀? 问题点数:30、回复次数:13Top

1 楼atEleven(@十一)回复于 2003-09-04 20:50:59 得分 24

1   一个标准的方法是:   把DATA写成一个Automation对象(从CCmdTarget继承)  
   
  2  
  如果你能保证组件是进程内组件(DLL),且只被单线程调用,可以把结构体指针当做一个LONG型数字传给客户端,反之(从客户端返回)亦然.比如说vb作为客户端:  
  dim   a   as   DATA  
  a.member1   =   1  
  a.member2   =   2  
  call   Obj.SendList(varPtr(a),n)   '请注意这里使用varPtr函数传指针.  
   
  3    
  可以把结构体数据压缩至一个SAFEARRAY中.或者当做字节序列(BYTE   ARRAY)压缩至SAFEARRAY中.  
   
  关于这个问题,http://www.microsoft.com/msj/0696/activex0696.aspx   有很详细的描述,是英文.我自己也做过类似的问题.有时间我们可以交流.  
   
   
  Top

2 楼atEleven(@十一)回复于 2003-09-04 20:56:03 得分 0

另:如果是ATL(支持双接口)可以参考这篇文档.  
   
  http://www.codeproject.com/atl/udtdemo.aspTop

3 楼ISAKEEPER()回复于 2003-09-07 15:10:52 得分 0

to   atEleven(@十一):您好!  
  我现在想用第一种方法  
  具体步骤:  
  CCommunication是从CCmdTarget继承,且在CCommunication.h中include   DATA.h,DATA在DATA.h中定义的。这样生成了一个ICCommunication接口,然后选择这个接口,添加方法(SendList),在选择方法参数类型时,没有DATA;如果手工修改的话,编译不过。  
  E:\myprg\CommLan_0906\Communication.cpp(66): DISP_FUNCTION(CCommunication,   "SendList",   SendList,   VT_BOOL,   VTS_I2   VTS_I2)//关键这个地方“VTS_I2   VTS_I2”不知怎样修改?  
  E:\myprg\CommLan_0906\Communication.cpp(293):BOOL   CCommunication::SendList(DATA   data,   short   m)    
  E:\myprg\CommLan_0906\Communication.h(88): afx_msg   BOOL   SendList(DATA   data,   short   m);  
  3   occurrence(s)   have   been   found.  
   
  请详细指点,谢谢!  
  Top

4 楼atEleven(@十一)回复于 2003-09-07 16:43:20 得分 0

如果需要,我可以提供CData   的实现样例.  
   
  //====idl或odl文件================================================  
  //以Data作为automation对象出现在在IDL/ODL文件中.  
  library   Your_Lib  
  {  
  ......  
  //把struct   DATA包装为自动化对象,需要手工实现类class   CData   :   public   CCmdTarget  
  //下面是   dispatch   interface  
  [   uuid(E8E62570-B183-4976-83C8-55DDAA3CF0C0)   ]  
  dispinterface   IData  
  {  
          properties:  
          [id(1),   helpstring("属性   ldata")]   LONG   ldata;  
          [id(2),   helpstring("属性   sdata")]   BSTR   sdata;  
          methods:  
  };  
  //下面是   automation   class   的IDL声明    
  [   uuid(2A36D675-D176-4E3F-A93A-3D172C69EA57)   ]  
  coclass   AutoData  
  {  
          [default]   dispinterface   IData;  
  };  
  ......  
  }  
   
  //====   头文件================================================  
  //   需要调用以   struct   Data   为参数的函数的类头文件.  
  class   CCall   :   public   CCmdTarget  
  {  
          ......  
          void   SetData(IDispatch*   data);  
  }  
   
  //====   cpp   文件================================================  
  //   需要调用以   struct   Data   为参数的函数的类cpp文件  
  DISP_FUNCTION_ID(Cax1Ctrl,   "SetData",   dispidSetData,   SetData,   VT_EMPTY,   VTS_DISPATCH)  
  void   CCall::SetData(IDispatch*   data)  
  {  
          AFX_MANAGE_STATE(AfxGetStaticModuleState());  
          //这个函数得到struct   Data,需要手工实现  
          //可以通过类CData和接口IDispatch的指针偏移量得到.  
          DATA*   pData   =   CData::GetDataFromIDisp(data);    
          //无需释放pData指针  
  }  
  Top

5 楼atEleven(@十一)回复于 2003-09-07 16:50:25 得分 0

还有,在ODL文件中定义了IData之后,可以手工修改SetData的IDispatch为IData  
  这样在生成的类型库文件中(比如说vb中打开)可以直接识别IData自动化接口.  
   
  [id(1),   helpstring("方法SetData")]   void   SetData(IData*   data);   //这里.  
   
  vb中可以这样调用:  
   
  dim   objdata   as   AutoData               //AutoData是ODL文件中coclass的名字  
  set   objdata   =   new   AutoData    
  objdata.ldata   =   100  
  objdata.sdata   =   "some   string"  
  objCall.SetData   objdata  
  Top

6 楼Microsoftadherent(王万新)回复于 2003-09-08 09:46:40 得分 1

在《COM精彩编程实例》中有一个专门的例子。Top

7 楼XXandOO(麦猪)回复于 2003-09-08 11:18:21 得分 5

如果客户是C++程序可在idl文件中定义这个结构体,并使用其作为借口函数的参数;如果客户是vb或脚本语言,则借口函数的参数须是OLE变量,一般来说使用idispatch/idispatch*作为参数类型。Top

8 楼ISAKEEPER()回复于 2003-09-08 13:08:38 得分 0

TO   XXandOO(麦猪):  
  我是用MFC写的COM  
   
   
   
  to   atEleven(@十一):您好!  
   
  我按照你的提示试验了一下,还是有以下错误:  
  我在Communication.h中定义了  
    bool   SendList(IDispatch*   data,DWORD   );但还是出错啊  
   
  E:\myprg\ComLan0908\Communication.cpp(60)   :   error   C2065:   'dispidSetData'   :   undeclared   identifier  
  E:\myprg\ComLan0908\Communication.cpp(283)   :   error   C2511:   'SendList'   :   overloaded   member   function   'bool   (struct   IDispatch   *,short)'   not   found   in   'CCommunication'  
                  e:\myprg\comlan0908\communication.h(45)   :   see   declaration   of   'CCommunication'  
  Error   executing   cl.exe.Top

9 楼atEleven(@十一)回复于 2003-09-08 13:20:42 得分 0

需要定义dispid的啊.我给的都不是直接能编译的东东.Top

10 楼ISAKEEPER()回复于 2003-09-08 15:05:58 得分 0

我把所有与SendList()相关的语句写在下面,请帮我看看,谢谢  
   
  E:\myprg\ComLan0908\Communication.cpp(60): DISP_FUNCTION_ID(CCommunication,   "SendList",   IData,   SendList,   VT_BOOL,   VTS_DISPATCH   VTS_I2)  
  E:\myprg\ComLan0908\Communication.cpp(282):bool   CCommunication::SendList(IData*   data,short   n)    
  E:\myprg\ComLan0908\Communication.h(89): afx_msg   BOOL   SendList(IData*   data,DWORD   );  
   
  //     Class   information   for   CCommunication  
   
  [   uuid(3331CA64-3A34-4EE4-91A2-01125C196CFC)   ]  
  coclass   Communication  
  {  
  [default]   dispinterface   ICommunication;  
  };  
  //     Class   information   for   CData  
   
  [   uuid(E26B75C9-6724-420F-A54B-CF77E89D0BCE)   ]  
  coclass   Data  
  {  
  [default]   dispinterface   IData;  
  };  
   
  编译之后  
  E:\myprg\ComLan0908\ComLan0908.odl(31)   :   error   MIDL2025   :   syntax   error   :   expecting   a   type   specification   near   "IData"  
  E:\myprg\ComLan0908\ComLan0908.odl(31)   :   error   MIDL2026   :   cannot   recover   from   earlier   syntax   errors;   aborting   compilation    
  Error   executing   midl.exe.Top

11 楼atEleven(@十一)回复于 2003-09-08 16:14:25 得分 0

IData只是在ODL中定义,而不需要在h和cpp文件中定义。  
  IData需要在所有引用该接口前的地方定义。  
   
  我还是给你一个例子自己看吧。  
   
  Top

12 楼ISAKEEPER()回复于 2003-09-08 19:29:19 得分 0

谢谢啦   :)Top

13 楼ISAKEEPER()回复于 2003-09-14 09:51:12 得分 0

问题解决,但我是这样解决的  
   
  用LPDISPATCH   *   类型,来实现中间的转换的Top

相关问题

  • 自定义组件参数问题?
  • 请教返回自定义接口参数的问题
  • 自定义组件
  • 如何在COM组件的接口函数中传出自定义的结构?
  • 自定义组件问题
  • 自定义消息参数??
  • 如何在接口定义的方法参数中使用自定义类型参数?例如下面的:MENUSTYLE?
  • activex控件的接口方法的参数是一个自定义的结构体,请问如何传进来?
  • 如何写自定义组件?(自定义控件)
  • 如何测试自定义组件?

关键词

  • 接口
  • 组件
  • 函数
  • 文件
  • 结构
  • cpp
  • 客户
  • sendlist
  • myprg
  • ccommunication

得分解答快速导航

  • 帖主:ISAKEEPER
  • atEleven
  • Microsoftadherent
  • XXandOO

相关链接

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

广告也精彩

反馈

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