Originally posted by: yuexiang
who can help me
thanks!
Originally posted by: shailesh
Hey i am passing the variant variable to a function by preparing the data as follows. Can anybody tell me where is the problem in this code. I am not getting any error but it is not showing any data. Thanks
VariantInit(&MyVar);
MyVar.vt = VT_VARIANT | VT_ARRAY;
SAFEARRAY *pSA;
SAFEARRAYBOUND aDim[1];
// a one dimensional array
aDim[0].lLbound = 0;
aDim[0].cElements = 1938;
pSA = SafeArrayCreateVector (VT_VARIANT,0,1938);
void *pDest;
SafeArrayAccessData(pSA, &pDest);
memcpy(pDest, tblob.lpb, 1937); // Copy into array
SafeArrayUnaccessData(MyVar.parray);
MyVar.parray= pSA;
m_InkCtrl.SetImageData(MyVar);
SafeArrayDestroy(pSA); // destroy the array.
Originally posted by: Xu Fayan
Public Sub b(a() As Integer, d As Integer)
Dim sum As Integer
End Sub
VARIANT varTemp;
SafeArrayAccessData(varTemp.parray, &pDest);
Thanks advancedly.
I am going to use VB activeX dll in my VC++ project,
but I can't call VB's dll function like below, for the parameter is an array.
VB DLL
***************************************
Dim i As Integer
sum = 0
For i = 0 To d
sum = sum + CInt(a(i))
Next i
MsgBox CStr(sum)
****************************************
..............
VC Client
***************************************
varTemp.vt = VT_I4 | VT_ARRAY;
SAFEARRAYBOUND bound;
bound.cElements = 4; // Set up size of array
bound.lLbound = 0;
varTemp.parray = SafeArrayCreate(VT_I4, 1, &bound); // Create it
void* pDest;
memcpy(pDest, c, sizeof(c)); // Copy into array
SafeArrayUnaccessData(varTemp.parray);
// t is the object of VB DLL class
t->b(&varTemp.parray, (short *)&d);
*******************************************
Can any body can help me to solve it?
Originally posted by: Ryan Mills
I have a void* buffer of n bytes, which I can happily pass around functions using a SAFEARRAY. If I use it to persist data in my control (i.e., I have a control embedded in a web page), my control implements IPersistPropertyBag_Load and has to call:
pPropBag->Write(bstrPropertyName, &vVar));
...where vVar is a CComVariant object containing my SAFEARRAY. However, because the VARTYPE is VT_UI1|VT_ARRAY, the implementation of IPropertyBag sees a string of chars and therefore only stores data up to the first null character!!!!!!
ReplyOriginally posted by: Mike Pulice
I am new to COM but have a big project going, typical.
I was stuck on the large packets I have to handle so I figured go to CodeGuru. I was relieved when I saw your article. Thanks for posting it!
Also, thanks for the IStream hints too.
Mike
ReplyOriginally posted by: Volodymyr Kozatchenko
What design is quicker (and tackes less memory) for getting/putting in COM?
Variant 1) ATL using uviversal marsh. (i.e. oleautomation in .IDL
[id(1), helpstring("method GetData")] HRESULT PutDataV([in] VARIANT pVar);
[id(1), helpstring("method GetData")] HRESULT GetDataV([out] VARIANT pVar);
Variant 2) ATL using its proxy/stub marsh. dll (made with nmake...)
[id(2), helpstring("method PutFoo")]
HRESULT PutFoo([in] short m, [in, size_is(m)] char * pbyte);
[id(3), helpstring("method GetFoo")] HRESULT GetFoo([in] short ms, [out, size_is(ms)] unsigned char * pbyte);
Thank you.
Reply
Originally posted by: Riccardo Raccuglia
if I reading 4096 byte from files I can alloc a safe array with cElements = 4096 / sizeof(UINT) ?
Originally posted by: Unsin
Thanks
How do we pass an array of user-defined structures via COM from a vb client to c++ server?
Originally posted by: DoubleJ
Here is fragment of server side code (no error checking):
STDMETHODIMP CServer::GetData( LPSTREAM *ppStm )
return hr;
Here is fragment of client side code (no error checking):
...
Hope this helps.
In case you have both client and server implemented in C++
the easiest way to pass any kind of data is to use IStream interface.
This interface can be marshalled across process/machine boundaries
so it is universal and safe method.
{
...
// Create stream in memory
// For better performance and to avoid reallocation
// you should preallocate memory using
// HGLOBAL hGlob = GlobalAlloc( GMEM_MOVEABLE, dwLen )
// and use hGlob instead of NULL in following function
HRESULT hr = CreateStreamOnHGlobal( NULL, TRUE, ppStm );
// Write some C++ data
hr = *ppStm->Write( &SomeValue, sizeof( SomeValue ), NULL );
// Write some COM objects that implement IPersistStream interface
OleSaveToStream( com_cast<IPersistStream>(pSomeObject), *ppStm );
...
// Data written
// Seek to start of stream (for client comfort)
ULARGE_INTEGER liNewPosition;
LARGE_INTEGER liOff;
LISet32(liOff, 0);
hr = *ppStm->Seek(liOff, STREAM_SEEK_SET, &liNewPosition);
}
CComPtr<IStream> pStm = NULL;
pServer->GetData( &pStm );
// Read C++ data from stream
pStm->Read( &SomeValue, sizeof( SomeValue ), NULL );
// Read COM objects
CComPtr<ISomeObject> pSomeObject = NULL;
OleLoadFromStream( pStm, __uuidof(ISomeObject), (LPVOID*)&pSomeObject );
...
Originally posted by: Yalin Wei
?
Reply