我想在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); };
这样不知道行不?不可以的话,应该怎样做?请各位大虾指点指点下.
struct A
{
int i;
char *p
..
}
然后在IDL文件里
dispinterface _Dacom1
{
properties:
methods: [id(DISPID_ABOUTBOX)] void AboutBox();
[id(1), helpstring("方法Func1")] void Func1(A & a); };
这样不知道行不?不可以的话,应该怎样做?请各位大虾指点指点下.
void Func1(A* a);
你得在idl文件中写上A的结构体声明
error MIDL2026 : cannot recover from earlier syntax errors; aborting compilation例如我在一个DATA.H文件里定义一结构:
typedef struct _sHeadPack
{
char FrameFlag;//帧标志 1B
short DevAddr;//设备地址 2B
char FramType;//帧类型(00公用帧,01动力设备帧,02~FF备用) 1B
char Rev;//保留字段默认为0 1B
_sHeadPack()
:DevAddr(0)
{
;
}
}HEADPACK;然后在idl文件
#include "data.h"再[id(1), helpstring("方法Func1")] void Func1(HEADPACK& a);
编译就会出错.
[id(1), helpstring("方法Func1")] void Func1(HEADPACK* a);
且在
DISP_FUNCTION_ID(Cacom1Ctrl, "Func1", dispidFunc1, Func1, VT_I4, VTS_NONE)
这个地方也不知该改成怎样才行.
能否举个例子看看啊.谢谢了.
// test_atl.idl : IDL source for test_atl
//// This file will be processed by the MIDL tool to
// produce the type library (test_atl.tlb) and marshalling code.import "oaidl.idl";
import "ocidl.idl";
typedef struct
{
char* p;
int x;
}testStru;[
object,
uuid(A50DD87B-5545-49B2-BB90-9AD67FA706E5),
dual,
nonextensible,
helpstring("Ialt_test Interface"),
pointer_default(unique)
]
interface Ialt_test : IDispatch{
[id(1), helpstring("method Doing")] HRESULT Doing([in,out]testStru*);
};
[
uuid(5AE5CCB8-575E-4E06-A866-657FDB7E1CCA),
version(1.0),
helpstring("test_atl 1.0 Type Library")
]
library test_atlLib
{
importlib("stdole2.tlb");
[
uuid(678B0D83-FB24-485C-B25C-F335B072041C),
helpstring("alt_test Class")
]
coclass alt_test
{
[default] interface Ialt_test;
};
};
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
/* File created by MIDL compiler version 7.00.0500 */
/* at Fri May 30 17:22:04 2008
*/
/* Compiler settings for test_atl.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 COM_NO_WINDOWS_H
#include "windows.h"
#include "ole2.h"
#endif /*COM_NO_WINDOWS_H*/#ifndef __test_atl_h__
#define __test_atl_h__#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif/* Forward Declarations */ #ifndef __Ialt_test_FWD_DEFINED__
#define __Ialt_test_FWD_DEFINED__
typedef interface Ialt_test Ialt_test;
#endif /* __Ialt_test_FWD_DEFINED__ */
#ifndef __alt_test_FWD_DEFINED__
#define __alt_test_FWD_DEFINED__#ifdef __cplusplus
typedef class alt_test alt_test;
#else
typedef struct alt_test alt_test;
#endif /* __cplusplus */#endif /* __alt_test_FWD_DEFINED__ */
/* header files for imported files */
#include "oaidl.h"
#include "ocidl.h"#ifdef __cplusplus
extern "C"{
#endif
/* interface __MIDL_itf_test_atl_0000_0000 */
/* [local] */ typedef /* [public][public] */ struct __MIDL___MIDL_itf_test_atl_0000_0000_0001
{
unsigned char *p;
int x;
} testStru;extern RPC_IF_HANDLE __MIDL_itf_test_atl_0000_0000_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_test_atl_0000_0000_v0_0_s_ifspec;#ifndef __Ialt_test_INTERFACE_DEFINED__
#define __Ialt_test_INTERFACE_DEFINED__/* interface Ialt_test */
/* [unique][helpstring][nonextensible][dual][uuid][object] */
EXTERN_C const IID IID_Ialt_test;#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("A50DD87B-5545-49B2-BB90-9AD67FA706E5")
Ialt_test : public IDispatch
{
public:
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Doing(
/* [out][in] */ testStru *__MIDL__Ialt_test0000) = 0;
};
#else /* C style interface */ typedef struct Ialt_testVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
Ialt_test * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */
__RPC__deref_out void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
Ialt_test * This);
ULONG ( STDMETHODCALLTYPE *Release )(
Ialt_test * This);
HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
Ialt_test * This,
/* [out] */ UINT *pctinfo);
HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
Ialt_test * This,
/* [in] */ UINT iTInfo,
/* [in] */ LCID lcid,
/* [out] */ ITypeInfo **ppTInfo);
HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
Ialt_test * 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 )(
Ialt_test * 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);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Doing )(
Ialt_test * This,
/* [out][in] */ testStru *__MIDL__Ialt_test0000);
END_INTERFACE
} Ialt_testVtbl; interface Ialt_test
{
CONST_VTBL struct Ialt_testVtbl *lpVtbl;
}; #ifdef COBJMACROS
#define Ialt_test_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define Ialt_test_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) ) #define Ialt_test_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define Ialt_test_GetTypeInfoCount(This,pctinfo) \
( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) #define Ialt_test_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) #define Ialt_test_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) #define Ialt_test_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )
#define Ialt_test_Doing(This,__MIDL__Ialt_test0000) \
( (This)->lpVtbl -> Doing(This,__MIDL__Ialt_test0000) ) #endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __Ialt_test_INTERFACE_DEFINED__ */#ifndef __test_atlLib_LIBRARY_DEFINED__
#define __test_atlLib_LIBRARY_DEFINED__/* library test_atlLib */
/* [helpstring][version][uuid] */
EXTERN_C const IID LIBID_test_atlLib;EXTERN_C const CLSID CLSID_alt_test;#ifdef __cplusplusclass DECLSPEC_UUID("678B0D83-FB24-485C-B25C-F335B072041C")
alt_test;
#endif
#endif /* __test_atlLib_LIBRARY_DEFINED__ *//* Additional Prototypes for ALL interfaces *//* end of Additional Prototypes */#ifdef __cplusplus
}
#endif#endif
我发现IDL文件跟你的完全不同啊.
且IDL里的方法在CTRL文件里还对应一个调度映射如:
BEGIN_DISPATCH_MAP(Cacom1Ctrl, COleControl)
DISP_FUNCTION_ID(Cacom1Ctrl, "Func1", dispidFunc1, Func1, VT_I4, VTS_NONE)
END_DISPATCH_MAP()这里跟IDL必须保持对应关系才行.还有我用的是VS.net2005,对于:
[
object,
uuid(A50DD87B-5545-49B2-BB90-9AD67FA706E5),
dual,
nonextensible,
helpstring("Ialt_test Interface"),
pointer_default(unique)
]
uuid(A50DD87B-5545-49B2-BB90-9AD67FA706E5)这串序列号是自动生成还是手工按格式敲.本人还没深入了解过COM,所以认识较浅,不知能否指点一二.谢谢了.
mfc和atl实现有点不一样 文件扩展名不太一样.但本质是一样的
你看看有啥区别
// 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;
};};
/* 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;
};
#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 __cplusplusclass 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
在建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没法对应起来了.
我用MFC ACTIVE向导生成的OCX组件有三种选项:DLL,EXE,SERVER EXE.这其中默认选的好象是DLL,不知道这算不算是跨进程的组件.如果是的话那把一结构体序列化成字符串BSTR,传递字符串参数如BSTR *pData,那访问pData还是非法访问了客户端进程的内存啊(pData指向的不就是客户端那进程的内存吗).
不是的话那能否区分下这几选项代表啥.我试过选EXE好象程序调用它是都没法启动,SERVER EXE也一样结果.用ATL试验也是这样的效果.不知怎回事?这两天想开始写一COM组件,但对于这些问题一直有疑惑,望知道的兄弟能指点下,谢谢了.
使用线程套间的组件都需要代理/存根DLL,如果接口方法的参数都是标准参数类型的话,可以直接使用系统提供的代理存根。
无论组件是哪种类型,调用都是透明的,无论是进程内组件还是进程外组件,除了CoCreateInstance的参数有稍许不同,其它过程一模一样。参数跨线程或者跨进程传递完全被代理存根接口列集处理了,就像在本地线程调用方法一样。所以你举例的BSTR在客户端和服务端是两个独立的串,分属于不同的进程,不存在访问其它进程内存的问题。
我可能问的太不清楚了.这样的:
比如我想做一个将通过结构序列拷贝到BSTR*传进一COM组件,而COM组件功能是:1.根据参数BSTR*再转成对应的结构数据存入队列,然后我再使用这些数据,比如画图形或显示到COM里边自己的UI从而使客户端看到图形;2.在COM组件对已存在的某条数据记录做相应操作后客户端也必须知道的话大概应该怎么组建这个COM控件?
先建一EXE组件,然后再怎么使用回调?
而是在界面通过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();
};
例如:
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;
}