dcsimg
June 23, 2018
Hot Topics:

Passing Binary Data in COM

  • April 28, 2000
  • By Developer.com Staff
  • Send Email »
  • More Articles »

There are two ways we can pass binary data in COM. SAFEARRAY and a pointer. by using a buffer pointer , we can get the best performance.

Here is the method declared in server IDL:

HRESULT Transfer([in] long cbSize,      
                 [in, size_is(cbSize)] unsigned char cBuffer[])

Here is the client code:

ITargetObj * pITargeObj ;
HRESULT hRC = ::CoCreateInstance(CLSID_TargetObj, 
                                 NULL, 
                                 CLSCTX_SERVER,
                                 IID_ITargetObj, 
                                 (void **)&pITargetObj ) ;
if FAILED( hRC )
{
 AfxMessageBox( "Failed to make target object!" ) ;
 return FALSE ;
}
      
BYTE * pBuffer = (BYTE *)::CoTaskMemAlloc( 15 ) ;
CopyMemory( pBuffer, "HELLO WORLD!!!!", 15 ) ;
pITargetObj->Transfer( 15, pBuffer ) ;
::CoTaskMemFree( pBuffer ) ;
pITargetObj ->Release() ;
But it only working for a INPROC Server with an object supporting a custom interface. If the object supporting a dual and dispatch interface, only the first character is transferred from client to server. Because the size_is attribute is stripped out (it's not supported by Automation), and the type library is used to marshal the interface. Obviously, this will not do. By the way, one good way to pass an array that does work for dual and dispatch interfaces is to use a SAFEARRAY.

Using CBufferVariant

Well,It's seem we have to using the SAFEARRAY, It's easy for a VB program, but I wanna same to VC program. I'v created a class named CBufferVariant, What's the cool things:

Here is the method declared in server IDL:

HRESULT Transfer([in] VARIANT vData)      

Here is the server code:

STDMETHODIMP CTargeObj::Transfer(VARIANT Data)
{
 CBufferVariant bvData=Data;
 if(bvData.GetLength()==0)
  return S_OK;
 send(m_nSocketFD,bvData,bvData.GetLength(),0);
 return S_OK;
}

Here is the client code:

#include "BufferVariant.h"

ITargetObj * pITargeObj ;
HRESULT hRC = ::CoCreateInstance(CLSID_TargetObj, 
                                 NULL, 
                                 CLSCTX_SERVER,
                                 IID_ITargetObj, 
                                 (void **)&pITargetObj ) ;
if FAILED( hRC )
{
 AfxMessageBox( "Failed to make target object!" ) ;
 return FALSE ;
}

CBufferVariant bvData;

SomeStruct stData;
bvData.AssignData(&stData,sizeof(SomeStruct));
pITargetObj->Transfer( bvData );

bvData="Hello World!";
bvData+="\n";
pITargetObj->Transfer( bvData );

char buffer[2048];
File1.Read(buffer,2048);
bvData.AssignData(buffer,2048);
File2.Read(buffer,1024);
bvData.AppendData(buffer,1024);
pITargetObj->Transfer( bvData );

pITargetObj->Transfer( CBufferVariant("This is a ANSI string.") ) ;

pITargetObj->Release();

Downloads

Download source - 2 Kb






Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

By submitting your information, you agree that developer.com may send you developer offers via email, phone and text message, as well as email offers about other products and services that developer believes may be of interest to you. developer will process your information in accordance with the Quinstreet Privacy Policy.

Sitemap

×
We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.
Thanks for your registration, follow us on our social networks to keep up-to-date