我想在COM接口处传递自定义的结构参数,好象接口处的参数是固定的那几个VARIANT,不知应该怎样实现.

zxmam 2008-05-30 03:33:01
我想在COM组件接口处传递一自定义的结构.如:
struct A
{
int i;
char *p
..
}


然后在IDL文件里
dispinterface _Dacom1
{
properties:
methods:

[id(DISPID_ABOUTBOX)] void AboutBox();
[id(1), helpstring("方法Func1")] void Func1(A & a);

};
这样不知道行不?

不可以的话,应该怎样做?请各位大虾指点指点下.
...全文
355 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
微wx笑 2012-03-06
  • 打赏
  • 举报
回复
我也遇到这样的问题了,呜呜……
jameshooo 2008-06-02
  • 打赏
  • 举报
回复
BSTR可以放心地跨线程或进程传递
zxmam 2008-06-02
  • 打赏
  • 举报
回复
怎么没人瞥下,分不够偶继续加
zxmam 2008-06-02
  • 打赏
  • 举报
回复
这样转换不知适不适合跨进程的传递.我想用内存拷贝不知行不行如:CMyStruct* pstruct =new CMyStruct; memcpy(pstruct,&pbstr,sizeof(CMyStruct))

还有就是我想用ATL做成窗口界面的COM,这样好画图,这样就可以在客户端创建此控件就可以直观的看图形了.就象用普通的CWnd控件一样.我原来做过的都是用MFC ACTIVE向导 生成的COM控件,默认就有一个*CTRL.CPP和*CTRL.H这个继承于COleControl里边就有OnDraw.但那样好象上进程内组件,现在想用ATL做一跨进程的组件,我用VC.NET2005工具试过好象就没看到可以用向导建一继承COleControl这个基类的接口类.不知道怎么做.
sigh02 2008-06-01
  • 打赏
  • 举报
回复
请问能不能让一个类作为参数啊?例如,Func1([in]int i, [out]class1 *p1),这样函数里根据参数i的不同,构造不同的对象?
jameshooo 2008-06-01
  • 打赏
  • 举报
回复
可以使用一个[in,out]BSTR* pbstr的参数来完成传递和回传的动作,结构体能放入BSTR,但是结构里面不要使用指针类型。
例如:
HRESULT __stdcall COcx::InOutFunc(BSTR* pbstr)
{
// 以下是接收数据
CMyStruct* pstruct = (CMyStruct*)(*pbstr); // 转换成结构
// 使用结构
SysFreeString(*pbstr); // 释放旧串

// 以下是返回数据
CMyStruct2 struct2;
struct2.abc = 10;
...
*pbstr = SysAllocStringByteLen((char*)&struct2, sizeof(struct2));

return S_OK;
}
zxmam 2008-06-01
  • 打赏
  • 举报
回复
都没人路过吗?我急啊,各位大师们帮帮忙吧,跪谢了
  • 打赏
  • 举报
回复
你早说你要跨进程传递.

你把你的结构体序列化成字符串,传递字符串.
zxmam 2008-06-01
  • 打赏
  • 举报
回复
对了,忘说一下,我在客户端用COM时不是通过CoCreateInstance,COM类也是对于Cwnd而言即主要做界面
而是在界面通过prgid获得CLSID,再create此控件如在客户端使用前创建下面COM对应接口类:
class COcx1 : public CWnd
{
protected:
DECLARE_DYNCREATE(COcx1)
public:
CLSID const& GetClsid()
{
static CLSID const clsid
= { 0x13407538, 0x50d, 0x46d4, { 0x96, 0xb3, 0x7f, 0x4d, 0x12, 0x2, 0xe1, 0x5c } };
return clsid;
}
virtual BOOL Create(LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd, UINT nID,
CCreateContext* pContext = NULL)
{ return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID); }

BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle,
const RECT& rect, CWnd* pParentWnd, UINT nID,
CFile* pPersist = NULL, BOOL bStorage = FALSE,
BSTR bstrLicKey = NULL)
{ return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID,
pPersist, bStorage, bstrLicKey); }

// Attributes
public:

// Operations
public:
void Func1(BSTR* pData);
void AboutBox();
};
zxmam 2008-06-01
  • 打赏
  • 举报
回复
楼上的意思是我在客户端传递一BSTR*,而服务端COM组件自己会将此BSTR*拷贝到自己的进程内存,在里边进行操作不会影响到外进程客户端传递的BSTR*里的内容了.
我可能问的太不清楚了.这样的:
比如我想做一个将通过结构序列拷贝到BSTR*传进一COM组件,而COM组件功能是:1.根据参数BSTR*再转成对应的结构数据存入队列,然后我再使用这些数据,比如画图形或显示到COM里边自己的UI从而使客户端看到图形;2.在COM组件对已存在的某条数据记录做相应操作后客户端也必须知道的话大概应该怎么组建这个COM控件?
先建一EXE组件,然后再怎么使用回调?
jameshooo 2008-06-01
  • 打赏
  • 举报
回复
DLL是进程内组件;EXE/SERVER EXE是进程外组件,看需求来选择。
使用线程套间的组件都需要代理/存根DLL,如果接口方法的参数都是标准参数类型的话,可以直接使用系统提供的代理存根。
无论组件是哪种类型,调用都是透明的,无论是进程内组件还是进程外组件,除了CoCreateInstance的参数有稍许不同,其它过程一模一样。参数跨线程或者跨进程传递完全被代理存根接口列集处理了,就像在本地线程调用方法一样。所以你举例的BSTR在客户端和服务端是两个独立的串,分属于不同的进程,不存在访问其它进程内存的问题。
zxmam 2008-06-01
  • 打赏
  • 举报
回复
我比你还菜,结构都不知怎传,不过akirya倒是说挺清楚的,但偶还是有个问题不清楚.
我用MFC ACTIVE向导生成的OCX组件有三种选项:DLL,EXE,SERVER EXE.这其中默认选的好象是DLL,不知道这算不算是跨进程的组件.如果是的话那把一结构体序列化成字符串BSTR,传递字符串参数如BSTR *pData,那访问pData还是非法访问了客户端进程的内存啊(pData指向的不就是客户端那进程的内存吗).
不是的话那能否区分下这几选项代表啥.我试过选EXE好象程序调用它是都没法启动,SERVER EXE也一样结果.用ATL试验也是这样的效果.不知怎回事?这两天想开始写一COM组件,但对于这些问题一直有疑惑,望知道的兄弟能指点下,谢谢了.

  • 打赏
  • 举报
回复
那些是系统定义的,当然没有对应的了

你用VTS_PUI1 代替把。然后自己强制转化。
zxmam 2008-05-31
  • 打赏
  • 举报
回复
那样可能不行,因为进程之间是没法访问各自的内存的.如果用VTS_PUI1等于传递一指向客户端进程的内存指针,传递进来后COM进程是应该是没法访问这块内存的,这样不非法操作了吗?
zxmam 2008-05-31
  • 打赏
  • 举报
回复
不行啊,主要是在IDL文件修改了[id(1), helpstring("方法Func1")] void Func1(testStru * pData);后
在建MFC ACTIVE组件时默认生成的**CTRL.CPP,*CTRL.H里边:
.H:
protected:
void Func1(BSTR* pData);
.CPP:
// 调度映射

BEGIN_DISPATCH_MAP(Cactv1Ctrl, COleControl)
DISP_FUNCTION_ID(Cactv1Ctrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
DISP_FUNCTION_ID(Cactv1Ctrl, "Func1", dispidFunc1, Func1, VT_EMPTY, VTS_PBSTR)<--1
END_DISPATCH_MAP()
1处没有对应的testStru 类型,只有接口默认的一些参数,这样就CPP与IDL没法对应起来了.
zxmam 2008-05-31
  • 打赏
  • 举报
回复
有点晕,我先试下.
  • 打赏
  • 举报
回复

#ifdef COBJMACROS


#define _DxxxxxxxEvents_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )

#define _DxxxxxxxEvents_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )

#define _DxxxxxxxEvents_Release(This) \
( (This)->lpVtbl -> Release(This) )


#define _DxxxxxxxEvents_GetTypeInfoCount(This,pctinfo) \
( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) )

#define _DxxxxxxxEvents_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) )

#define _DxxxxxxxEvents_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) )

#define _DxxxxxxxEvents_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )

#endif /* COBJMACROS */


#endif /* C style interface */


#endif /* ___DxxxxxxxEvents_DISPINTERFACE_DEFINED__ */


EXTERN_C const CLSID CLSID_xxxxxxx;

#ifdef __cplusplus

class DECLSPEC_UUID("746B35C2-AF46-41E5-A8EA-131489E1C44A")
xxxxxxx;
#endif
#endif /* __xxxxxxxLib_LIBRARY_DEFINED__ */

/* Additional Prototypes for ALL interfaces */

/* end of Additional Prototypes */

#ifdef __cplusplus
}
#endif

#endif


  • 打赏
  • 举报
回复


/* this ALWAYS GENERATED file contains the definitions for the interfaces */


/* File created by MIDL compiler version 7.00.0500 */
/* at Fri May 30 23:08:10 2008
*/
/* Compiler settings for xxxxxxx.idl:
Oicf, W1, Zp8, env=Win32 (32b run)
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
//@@MIDL_FILE_HEADING( )

#pragma warning( disable: 4049 ) /* more than 64k source lines */


/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 475
#endif

#include "rpc.h"
#include "rpcndr.h"

#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif // __RPCNDR_H_VERSION__


#ifndef __xxxxxxx_h__
#define __xxxxxxx_h__

#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

/* Forward Declarations */

#ifndef ___Dxxxxxxx_FWD_DEFINED__
#define ___Dxxxxxxx_FWD_DEFINED__
typedef interface _Dxxxxxxx _Dxxxxxxx;
#endif /* ___Dxxxxxxx_FWD_DEFINED__ */


#ifndef ___DxxxxxxxEvents_FWD_DEFINED__
#define ___DxxxxxxxEvents_FWD_DEFINED__
typedef interface _DxxxxxxxEvents _DxxxxxxxEvents;
#endif /* ___DxxxxxxxEvents_FWD_DEFINED__ */


#ifndef __xxxxxxx_FWD_DEFINED__
#define __xxxxxxx_FWD_DEFINED__

#ifdef __cplusplus
typedef class xxxxxxx xxxxxxx;
#else
typedef struct xxxxxxx xxxxxxx;
#endif /* __cplusplus */

#endif /* __xxxxxxx_FWD_DEFINED__ */


#ifdef __cplusplus
extern "C"{
#endif


/* interface __MIDL_itf_xxxxxxx_0000_0000 */
/* [local] */

typedef /* [public][public] */ struct __MIDL___MIDL_itf_xxxxxxx_0000_0000_0001
{
unsigned char *p;
int x;
} testStru;



extern RPC_IF_HANDLE __MIDL_itf_xxxxxxx_0000_0000_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_xxxxxxx_0000_0000_v0_0_s_ifspec;


#ifndef __xxxxxxxLib_LIBRARY_DEFINED__
#define __xxxxxxxLib_LIBRARY_DEFINED__

/* library xxxxxxxLib */
/* [control][helpstring][helpfile][version][uuid] */


EXTERN_C const IID LIBID_xxxxxxxLib;

#ifndef ___Dxxxxxxx_DISPINTERFACE_DEFINED__
#define ___Dxxxxxxx_DISPINTERFACE_DEFINED__

/* dispinterface _Dxxxxxxx */
/* [helpstring][uuid] */


EXTERN_C const IID DIID__Dxxxxxxx;

#if defined(__cplusplus) && !defined(CINTERFACE)

MIDL_INTERFACE("37881E6C-8D11-4DB5-8698-90A4F802D30D")
_Dxxxxxxx : public IDispatch
{
};

#else /* C style interface */

typedef struct _DxxxxxxxVtbl
{
BEGIN_INTERFACE

HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
_Dxxxxxxx * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */
__RPC__deref_out void **ppvObject);

ULONG ( STDMETHODCALLTYPE *AddRef )(
_Dxxxxxxx * This);

ULONG ( STDMETHODCALLTYPE *Release )(
_Dxxxxxxx * This);

HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
_Dxxxxxxx * This,
/* [out] */ UINT *pctinfo);

HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
_Dxxxxxxx * This,
/* [in] */ UINT iTInfo,
/* [in] */ LCID lcid,
/* [out] */ ITypeInfo **ppTInfo);

HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
_Dxxxxxxx * This,
/* [in] */ REFIID riid,
/* [size_is][in] */ LPOLESTR *rgszNames,
/* [range][in] */ UINT cNames,
/* [in] */ LCID lcid,
/* [size_is][out] */ DISPID *rgDispId);

/* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
_Dxxxxxxx * This,
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID riid,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS *pDispParams,
/* [out] */ VARIANT *pVarResult,
/* [out] */ EXCEPINFO *pExcepInfo,
/* [out] */ UINT *puArgErr);

END_INTERFACE
} _DxxxxxxxVtbl;

interface _Dxxxxxxx
{
CONST_VTBL struct _DxxxxxxxVtbl *lpVtbl;
};



#ifdef COBJMACROS


#define _Dxxxxxxx_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )

#define _Dxxxxxxx_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )

#define _Dxxxxxxx_Release(This) \
( (This)->lpVtbl -> Release(This) )


#define _Dxxxxxxx_GetTypeInfoCount(This,pctinfo) \
( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) )

#define _Dxxxxxxx_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) )

#define _Dxxxxxxx_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) )

#define _Dxxxxxxx_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )

#endif /* COBJMACROS */


#endif /* C style interface */


#endif /* ___Dxxxxxxx_DISPINTERFACE_DEFINED__ */


#ifndef ___DxxxxxxxEvents_DISPINTERFACE_DEFINED__
#define ___DxxxxxxxEvents_DISPINTERFACE_DEFINED__

/* dispinterface _DxxxxxxxEvents */
/* [helpstring][uuid] */


EXTERN_C const IID DIID__DxxxxxxxEvents;

#if defined(__cplusplus) && !defined(CINTERFACE)

MIDL_INTERFACE("2D4659DB-E544-4D55-9D41-E9CD96AABD0A")
_DxxxxxxxEvents : public IDispatch
{
};

#else /* C style interface */

typedef struct _DxxxxxxxEventsVtbl
{
BEGIN_INTERFACE

HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
_DxxxxxxxEvents * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */
__RPC__deref_out void **ppvObject);

ULONG ( STDMETHODCALLTYPE *AddRef )(
_DxxxxxxxEvents * This);

ULONG ( STDMETHODCALLTYPE *Release )(
_DxxxxxxxEvents * This);

HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
_DxxxxxxxEvents * This,
/* [out] */ UINT *pctinfo);

HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
_DxxxxxxxEvents * This,
/* [in] */ UINT iTInfo,
/* [in] */ LCID lcid,
/* [out] */ ITypeInfo **ppTInfo);

HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
_DxxxxxxxEvents * This,
/* [in] */ REFIID riid,
/* [size_is][in] */ LPOLESTR *rgszNames,
/* [range][in] */ UINT cNames,
/* [in] */ LCID lcid,
/* [size_is][out] */ DISPID *rgDispId);

/* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
_DxxxxxxxEvents * This,
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID riid,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS *pDispParams,
/* [out] */ VARIANT *pVarResult,
/* [out] */ EXCEPINFO *pExcepInfo,
/* [out] */ UINT *puArgErr);

END_INTERFACE
} _DxxxxxxxEventsVtbl;

interface _DxxxxxxxEvents
{
CONST_VTBL struct _DxxxxxxxEventsVtbl *lpVtbl;
};
  • 打赏
  • 举报
回复
这个是MFC的
你看看有啥区别


// xxxxxxx.idl : ActiveX 控件项目的类型库源。

// 此文件将由 MIDL 编译器工具处理以
// 产生类型库(xxxxxxx.tlb),该类型库将成为
// xxxxxxx.ocx.

#include <olectl.h>
#include <idispids.h>

typedef struct
{
char* p;
int x;
}testStru;


[ uuid(2DC06B3F-EBE2-4096-9178-DC4C5BD42987), version(1.0),
helpfile("xxxxxxx.hlp"),
helpstring("xxxxxxx ActiveX 控件模块"),
control ]
library xxxxxxxLib
{
importlib(STDOLE_TLB);

// CxxxxxxxCtrl 的主调度接口

[ uuid(37881E6C-8D11-4DB5-8698-90A4F802D30D),
helpstring("xxxxxxx Control 的调度接口")]
dispinterface _Dxxxxxxx
{
properties:
methods:

[id(DISPID_ABOUTBOX)] void AboutBox(testStru*);
};

// CxxxxxxxCtrl 的事件调度接口

[ uuid(2D4659DB-E544-4D55-9D41-E9CD96AABD0A),
helpstring("xxxxxxx Control 的事件接口") ]
dispinterface _DxxxxxxxEvents
{
properties:
// 事件接口没有任何属性

methods:
};

// CxxxxxxxCtrl 的类信息

[ uuid(746B35C2-AF46-41E5-A8EA-131489E1C44A),
helpstring("xxxxxxx Control"), control ]
coclass xxxxxxx
{
[default] dispinterface _Dxxxxxxx;
[default, source] dispinterface _DxxxxxxxEvents;
};

};
  • 打赏
  • 举报
回复
com只有一种规范
mfc和atl实现有点不一样 文件扩展名不太一样.

但本质是一样的
加载更多回复(9)

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧