Re: passing a NULL pointer from vb6 to an ATL method
"John" <John@discussions.microsoft.com> wrote in message
news:28D7598A-416A-4B7A-AD18-C9448D953797@microsoft.com...
Brian,
The whole reason behind what I am doing is to get away from using a
safearray
and it's overhead. The server is mainly going to be used by C/C++ clients
but it
does need to support VB.
What I am trying to accomplish can be explained better in this sample
piece
of
code;
// On the Server side
HRESULT CSomeObj::get_List(short* plistitems, short* plist)
{
if (!plistitems) return E_POINTER;
*plistitems = 10;
if (plist) {
short i;
for (i=0; i<10; i++)
list[i] = i;
}
return S_OK;
}
// C/C++ client side
short nlist, *plist = NULL;
ComPtr<ISomeObj> pobj;
pobj.CoCreateInstance(CLSID_SomeObj);
pobj->get_List(&nlist, NULL); // query list
elements
plist = new short[nlist]; // allocate list
pobj->get_List(&nlist, plist); // get list
delete [] plist;
// now on the VB side I would like to perform the same
Dim obj as New someLib.SomeObj
Dim nlist as integer
Dim nlistitems () as integer
obj->list nlist, NULL // NULL for example purposes only
Redim listitems (0 to nlist)
obj->list nlist, listitems(0)
Why do you insist on doing it this way? You are making two round trips
rather than one. You are forcing the client to re-dimension the array. This
is completely unnecessary. The server can redimension it on behalf of the
client. Then you can code it as follows:
Dim obj as New someLib.SomeObj
Dim nlist as Integer
Dim nlistitems() as Integer
obj.list nlist
listitems = UBound(nlist) - LBound(nlist) + 1
Isn't that a lot cleaner?
Using a single property call for two different purposes (the first call to
determine how many elements to allocate, and the second call to fetch the
elements) really is not a clean interface definition. If you insist on your
approach, why not define a separate property called NoListElements, defined
as:
HRESULT CSomeObj::get_NoListElements ([out, retval] short* NoElements)
which clearly states the purpose of this property.
As a final word, you can pass a Null if the parameter is a VARIANT, as in:
HRESULT CComObj::get_List ([in, out] VARIANT *pV)
which would permit
obj.List Null
In this case pV->vt_type would be VT_NULL.
Brian