Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

COM question in regards to memory allocation

1 view
Skip to first unread message

lo...@multiverse.com

unread,
Mar 9, 1999, 3:00:00 AM3/9/99
to
Hopefully there is an easy solution to this...this is one of my first
forays in to COM programming.

What I originally had was a dll, mydll.dll. This had no COM in it
whatsover. It does not use MFC.

I then wrote a COM exe server to access functions in this DLL. I used
the ATL project wizard to do this. There are only 3 functions in the
original DLL I wanted to acces via COM: Initialize, ReadData, and
WriteData.

I added a COM object to the project and added methods for the
Initialize, ReadData, and WriteData.

In the constructor for the COM object (the file that has the
inheritance from CComObjectRootEx, CComCoClass, etc.) I new an
instance of the dll object. For arguments sake it looks something
like this:

public:
mydll* pmydllObj;

CMyComObject()
{
pmydllObj = new mydll;
}

Then, in the implementation for the three methods, I call the
functions from the dll, such as:

STDMETHODIMP CMyComObject::ReadData( unsigned char* data )
{
pmydllObj->ReadData( data );

return S_OK;
}

This builds fine. The client is an MFC dialog based app (very
simplistic). I call CoCreateInstance in the OnInitDialog and then I
have a message handler for when I press the 'ReadData' button. This
then does the following:

unsigned char tempResult[4];

((IMyComObject*)pmydllObj)->ReadDevice( reinterpret_cast<unsigned
char*>(&tempResult));


The problem is this: As I debug, I see that tempResult is at memory
location x. When it calls into the COM server, the memory of 'data'
is location y. Everything happens as it should, but obviously the
data is not getting to the client. In the IDL file, 'data' is an
[out, retval] attribute. I have tried using CoTaskMemAlloc on in the
Com ReadData function, but to no avail.

I'm sure its something simple, but I'm running out of ideas. Any and
all help would be greatly appreciated.

Thanks in advance,

Aaron Lukacsko
<lo...@multiverse.com>


Vincent Minden

unread,
Mar 10, 1999, 3:00:00 AM3/10/99
to
First, when you have an [out,retval] (or any parameter marked [out]), you
need to pass a pointer to the data type you want passed. Ie do:
STDMETHODIMP CMyComObject::ReadData( unsigned char ** data )
{
pmydllObj->ReadData( *data );

return S_OK;
}

especially when you are calling it like


((IMyComObject*)pmydllObj)->ReadDevice( reinterpret_cast<unsigned
char*>(&tempResult));

except it really should be

((IMyComObject*)pmydllObj)->ReadDevice( &tempResult);

The reinterpret cast that you did was probably to quiet a valid compiler
error about different levels of indirection.

Now, all the above would probably work, except you are walking all over
several rules of COM programming.
First, in COM, the server is usually responsible for allocating the memory
on [out] type parameters. This is not the case in what you are doing, you
are allocating the memory on the client side and filling it on the server
side.

I really would stick to the rules of COM memory allocation/deallocation of
parameters. These are as followes:
[in] type parameters - Allocated by the client, Deallocated by the client.
[in,out] type parameters - Allocated by the client, usually Reallocated by
the server, Deallocated by the client
[out] type paramters (including [out,retval]) - Allocated by the Server,
Deallocated by the client.

Second, unless you had a really pressing reasons not to, I would pass BSTR's
instead of char *, otherwise you won't beable to use the COM object from a
scripting language (should you ever want to at a later date) and it may not
be able to be used from VB. Also, since BSTRs are allocated with System
functions, you can allocate them in the server, and deallocate them in the
client without worrying about problems with memory allocation and freeing
across dll/server boundries.

Vincent Minden


<lo...@multiverse.com> wrote in message
news:36e54bb1...@msnews.microsoft.com...

Reginald Blue

unread,
Mar 10, 1999, 3:00:00 AM3/10/99
to
Two things:

1. You'll have better luck with COM questions in this newsgroup:

microsoft.public.win32.programmer.ole

2. Your mistake is in the IDL which you haven't shown. Change that
"unsigned char *" to "unsigned char **", and you should find it will work a
lot better. (You've told it you want to return one character...not a string
of characters.) Also, you'll need to tell it how many characters you're
returning OR specify the "string" attribute so it knows to look for NUL
terminated data.

HTH

--
Reginald Blue | Opinions expressed here do not
Natural Language Understanding | necessarily represent those of
Unisys Corporation | my employer.
|-------------------------------
| My email address is wrong, you
r...@NOSPAM.trsvr.tr.unisys.com | need to remove the obvious.

lo...@multiverse.com wrote in message
<36e54bb1...@msnews.microsoft.com>...

0 new messages