Passing arrays of structures in COM
Posted
by Reg Anderson
on March 5th, 1999
template "<"class T">" class CComArray { // Attributes private: int m_nSize; bool m_bOwner; VARIANT* m_pVariant; // Implemenation public: CComArray() :m_nSize(0),m_bOwner(false),m_pVariant(NULL) { } virtual ~CComArray() { Clear(); } void Clear() { if(m_bOwner && m_pVariant) { if(m_pVariant->parray) SafeArrayDestroy(m_pVariant->parray); m_pVariant->parray=NULL; VariantClear(m_pVariant); } m_nSize=0; m_bOwner=false; m_pVariant=NULL; } bool Initialize(VARIANT* pVar,int nSize,bool bOwner) { if(m_pVariant!=NULL || pVar==NULL || nSize<1) return false; VariantInit(pVar); pVar->vt=VT_ARRAY|VT_UI1; SAFEARRAYBOUND s= { nSize*sizeof(T),0 }; if((pVar->parray=SafeArrayCreate(VT_UI1,1,&s;))==NULL) return false; m_nSize=nSize; m_bOwner=bOwner; m_pVariant=pVar; return true; } bool Attach(VARIANT* pVar,bool bOwner) { if(m_pVariant!=NULL || pVar==NULL) return false; if(pVar->parray==NULL || pVar->vt!=(VT_ARRAY|VT_UI1)) return false; long nLBound=0L; long nUBound=0L; if(FAILED(SafeArrayGetLBound(pVar->parray,1,&nLBound;))) return false; if(FAILED(SafeArrayGetUBound(pVar->parray,1,&nUBound;))) return false; if(nUBound>0L) m_nSize=(int)(((nUBound-nLBound)+1L)/sizeof(T)); m_bOwner=bOwner; m_pVariant=pVar; return true; } int Size() { return m_nSize; } bool GetAt(int n,T& Item) { if(!m_pVariant || n<0 || n>=m_nSize) return false; LPBYTE pData; SafeArrayAccessData(m_pVariant->parray,(void**)&pData;); CopyMemory(&Item;,&pData;[n*sizeof(T)],sizeof(T)); SafeArrayUnaccessData(m_pVariant->parray); return true; } bool SetAt(int n,T& Item) { if(!m_pVariant || n<0 || n>=m_nSize) return false; LPBYTE pData; SafeArrayAccessData(m_pVariant->parray,(void**)&pData;); CopyMemory(&pData;[n*sizeof(T)],&Item;,sizeof(T)); SafeArrayUnaccessData(m_pVariant->parray); return true; } };
Download Source Code and Example
Last updated: 05 March 1999
Comments
Memory leak when sending event
Posted by Legacy on 06/08/2003 12:00amOriginally posted by: Filbert Fox
Passing arrays of structures in COM.
Posted by Legacy on 10/02/2002 12:00amOriginally posted by: Neeraj Garg
I need to pass array of structures to ASP. Can I do it ?
ReplyHow to pass Variant parameter to VBScript
Posted by Legacy on 11/17/2001 12:00amOriginally posted by: ddpanda
I have a ActiveX control which has a custom method:Add([in]short Num1,[in]short Num2,[out,retval]VARIANT *short),how can I get the return value of this method by VBScript
ReplyByte Alignment when recieveing structures and VariantClear too
Posted by Legacy on 06/05/2001 12:00amOriginally posted by: Arun
I have some code that does the same thing - passing arrays of UDT - i send and recieve structures to and from VB components across MTS deployed components
However the byte alignment used by my application is 1 and vb by default uses 4byte alignment. This is giving me problems.
is there a solution? right now iam trying to work around using #pragma packs but it just doesnt look so good enuff.
And abt the VAriantclear - is it really enuff to clean the UDT array ? will it go into each UDT and release BSTRs in it and release all the memory occupised by the array ?
ReplyHow to access SafeArray from a VB client...
Posted by Legacy on 12/09/2000 12:00amOriginally posted by: Vivek Oza
Working DCOM i get DISP_E_ARRAYISLOCKED, why?
Posted by Legacy on 03/02/2000 12:00amOriginally posted by: David Avramov
I work with VC++/6 .
Sometimes i get an exception DISP_E_ARRAYISLOCKED,meaning
"Memory is locked" , while working with DCOM.
Why do this happen,and what shall i do to resolve it?
Thanks,
Passing array of struct's to VB
Posted by Legacy on 01/26/2000 12:00amOriginally posted by: Rama Nadendla
Hi,
ReplyYou have an example of how we can pass the struct in COM/C++ env. How can i send it from COM/C++ env to VB.
Thanks in advance.
Will it work with structures containing pointers?
Posted by Legacy on 09/29/1999 12:00amOriginally posted by: Krishna Kadali
I might be missing something here, but I can't figure out how this approach would work when my structure contains some pointers like BSTR. Could some one explain me a little bit if this approach can work with structure containing pointers?
ReplyIs marshalling required for to pass this structure to a remote server??
Posted by Legacy on 07/09/1999 12:00amOriginally posted by: Kalyan
I used this ComArray template class for passing array of structures from COM client's to Inproc servers. But i failed to pass a structure containing a BSTR elements to a remote server. Is any marshalling support required??.
I suspect that the SetAt() fn copies only the top level pointers i.e, the BSTR [since BSTR being a ptr to a ptr] and not the data.
Any workaround,?? help is very much appreciated.
ReplyIs it really that simple?
Posted by Legacy on 03/16/1999 12:00amOriginally posted by: Carsten Traupe
When I'm right the clue of this approach lies in making the information typless (VARIANT) and hope that copying it in memory bit by bit later receives the correct structure.
But this assumes that the compiler always generates the same code for the class T on both sides of the COM barrier. When marshalling across system boundaries, for exsample from WinNT to Win3x this would crash in the same way than flattening the memory to a BSTR.
But maybe there is no generic and system independent way to marshall arbitrary data. I my opinion this is the case. Please tell me that I'm wrong.
Carsten.
ReplyLoading, Please Wait ...