Archived

This topic is now archived and is closed to further replies.

atlnewbie

*COM* how to return binary data from atl server

Recommended Posts

Hi all I need help moving binary data from the atl server to the client. Say I want to make an atl com server with a method "LoadBitmap". I want LoadBitmap to return to the client the binary data of some bitmap file. I started off with BSTRs after I read that it was possible to move binary with BSTR on only 32bit or only 16bit systems. I could not get this to work - my client reported that the string returned is length 0 (on the server the buffer''s first byte was 00 so I assume this is the null termination problem). Last time i checked i dont have any 16 bit systems other than my super nintendo - correct me if I''m wrong. Ok ok I think they probably mean win 3.1 but still I don''t see how that has anything to do with my system (win98, msvc++6, using SCOL engine for the client). I searched online and read several references which point to SAFEARRAYS and "VARIANT containing a SAFEARRAY" as the "proper" way to move binary data (for example in the MSDN - see SAFEARRAY entry). So... 1)I need more information on this. If anybody has some code that would be great - or a link to an article / tutorial / whatever. 2)If there *is* a way to implement this with BSTR only I would be even happier. 3)Could anybody explain what the deal is with the 32bit 16bit rules for BSTR or point to reference on this. Thanks for taking time to read this, your bewildered atlnewbie

Share this post


Link to post
Share on other sites

Hi again

Just wanted to say that I''ve solved my specific problem
by using BSTRs and using the 16th bit to flag for the zeroes.
This would normally be lame but my client side only needs 15 bits anyway :p

I am still interested in answers to the questions in
my the first post though

Also I just want to say that I am using "FreeImage" libraries
for opening image files and it is a nice little API - I
recommend it.

atlnewbie

Share this post


Link to post
Share on other sites
One thing that you might consider trying is using the IStream and IStorage interfaces. The IStream interface is pretty simple and is quite similar to a file. You basically Write() data to the stream in the server and then Read() the data in the client. The IStorage interface is used to create the stream(s).

As far as using BSTRs, I THINK there is a way to set the length of the BSTR independent of where null characters are located in the string. I think the function you want is SysAllocStringByteLen() instead of SysAllocString().

Share this post


Link to post
Share on other sites
I made my own interface and a couple of coclasses to implement it:

IBlob manages a small chunk of data, and IPacketBuffer maintains a circular buffer of blobs.

I look at using IStream and IStorage, but they were more complicated than what I needed - and I doubt the coclass uses a circular buffer like I wanted to.

For that matter, you can just return a DWORD and a BYTE*
  
HRESULT GetChunk([out]DWORD* pdwBytes, [out, size_is(dwBytes)]BYTE* pbData);


  
[
object,
uuid(FBDF4940-0A81-4830-9D8F-2BD7EA1940F4),
version(1.0),
pointer_default(unique)
]
interface IBlob : IUnknown
{
HRESULT Read(DWORD dwBytes, BYTE* pDest);
HRESULT Write(DWORD dwBytes, const BYTE* pSource);
HRESULT Size([out, retval] DWORD* pdwBytes);
HRESULT Lock(BYTE** ppBlob, DWORD* pdwBytes);
HRESULT UnLock();
HRESULT IsLocked();
};

[
object,
uuid(32AA68C5-D442-44c5-9F67-782606129151),
version(1.0),
pointer_default(unique)
]
interface IPacketBuffer : IUnknown
{
HRESULT Reserve(IBlob** ppBlob, DWORD dwBytesToWrite);
HRESULT Commit(IBlob* pBlob);
HRESULT Read(IBlob** ppBlob, DWORD* pdwBytesRead);
HRESULT Free(IBlob* pBlob);
};

Share this post


Link to post
Share on other sites