|
Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com |
Passing UDT's
From: Christopher Lawton (clawton
CSC.COM)
Date: Mon Jul 28 2003 - 17:55:13 CDT
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi All -
I'm confused about passing UDT's in C++. More specifically, cleanup after
you're done using the UDT.
I've been stress testing the client side code and the code shown below is
called hundreds of times.
It looks like it leaks a bit of memory & handles as the main object is
created and released. BoundsChecker
complains about some interfaces not being released. But. as I point out in
my questions, I get problems when
I do what I think I should be doing....
My questions are:
1) How come in the client the reference counts to pTypeLib and pTypeInfo
are still 1 even after the call to Release()?
a) If I add code to continue to call release() until the reference
count equals zero the client will crash on the call
to release of pRecInfo with an access violation.
2) If I call release on pTypeInfo until the reference count equals zero it
crashes with an access violation on the next release
on pTypeLib. Any ideas why?
3) Why, if I call SafeArrayDestroy() on the server does it cause the client
to get an access violation the next time even though
everything is (theoretically) clean up and is brand new in the next
iteration?
4) And a more general question: The server never uses the pRecInfo field in
the variant but everything seems to be working
just fine. If I release it in the server things start crashing again. Is
it there only for automation? Do I really need to pass UDT's
like this if I just use C++? (I would like to keep the server automation
compliant.)
Right now the server is Out of Process on the same machine as the client.
(Using Windows 2000 sp3)
Thanks for any info!
Chris
Here's the code:
I have the following IDL:
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(0266FFAC-939F-4FB5-822D-080D195D0E28),
dual,
helpstring("ICSCAlbatch Interface"),
pointer_default(unique)
]
interface ICSCAlbatch : IDispatch
{
[id(1), helpstring("method AddSearchDatabases")] HRESULT
AddSearchDatabases([in] VARIANT *theArray, [out, retval] int *ret);
/* rest omitted */
};
[
uuid(D9021278-0802-4E9F-9B40-93981A7380F3),
version(1.0),
helpstring("CSCSearcher 1.0 Type Library")
]
library CSCSEARCHERLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
typedef [uuid(84FBC153-6064-4ABC-BDE8-0604F7b3574D)] struct
SearchDatabaseStruct {
BSTR filename;
BSTR hostname;
} SearchDatabaseStruct;
[
uuid(EDE5D0C2-D73E-4EC1-B1A9-3A8B514A9BD6),
helpstring("CSCAlbatch Class")
]
coclass CSCAlbatch
{
[default] interface ICSCAlbatch;
};
};
And on the client I make the call as follows (which is in a larger loop):
(Error checking omitted)
HRESULT hr = CoCreateInstance(CLSID_CSCAlbatch, NULL, CLSCTX_SERVER,
IID_ICSCAlbatch, (void**)&m_pCSCAlbatch);
hr = LoadRegTypeLib(LIBID_CSCSEARCHERLib, 1, 0, GetUserDefaultLCID(),
&pTypeLib);
hr = pTypeLib->GetTypeInfoOfGuid(UUID_SearchDatabaseStruct,
&pTypeInfo);
hr = GetRecordInfoFromTypeInfo(pTypeInfo, &m_pRecInfo);
// All done with pTypeInfo and pTypeLib
long pTypeInfoRelCount = pTypeInfo->Release();
long pTypeLibRelCount = pTypeLib->Release();
TRACE("pTypeInfoRelCount=%d\n",pTypeInfoRelCount);
TRACE("pTypeLibRelCount=%d\n",pTypeLibRelCount);
VARIANT variant; // to hold the safearray
SAFEARRAYBOUND sab;
sab.cElements = 2;
sab.lLbound = 0;
// Build the safearray
SAFEARRAY * pSa;
pSa = SafeArrayCreateEx(VT_RECORD, 1, &sab, m_pRecInfo);
PVOID pvData;
SafeArrayAccessData(pSa, &pvData);
SearchDatabaseStruct * pTest;
pTest = (SearchDatabaseStruct *)pvData;
pTest[0].filename = SysAllocString(L"d:
\\dbsa\\pd_20030610\\030610_5.ald");
pTest[0].hostname = SysAllocString(L"lrsrv1");
pTest[1].filename = SysAllocString(L"d:
\\dbsa\\pd_20030610\\030610_6.ald");
pTest[1].hostname = SysAllocString(L"lrsrv1");
SafeArrayUnaccessData(pSa);
// Put the safe array in the variant
VariantInit(&variant);
V_VT(&variant) = VT_ARRAY|VT_RECORD;
V_ARRAY(&variant) = pSa;
// Use the data...
TRACE("[client] About to call AddSearchDatabases()...\n");
int ret=0;
hr = m_pCSCAlbatch->raw_AddSearchDatabases(&variant, &ret);
TRACE("[client] done.\n");
// Clean up...
for (UINT i=0; i<sab.cElements; i++) {
SysFreeString(pTest[i].filename);
SysFreeString(pTest[i].hostname);
}
SafeArrayDestroy(pSa);
long recrelcount = m_pRecInfo->Release();
TRACE("recrelcount = %d\n",recrelcount);
/* blah...blah...blah */
m_pCSCAlbatch->Release();
And on the server:
STDMETHODIMP CCSCAlbatch::AddSearchDatabases(VARIANT *theArrary, int *ret)
{
TRACE("Start AddSearchDatabases()\n");
// How many elements did we get?
DWORD count = theArrary->parray->rgsabound->cElements;
// Get a pointer to the array.
SearchDatabaseStruct *theData=NULL;
SafeArrayAccessData(theArrary->parray, (void**)&theData);
// Use the data....
for (DWORD i=0; i<count; i++) {
CString aDB;
CString filename = theData[i].filename;
CString hostname = theData[i].hostname;
/* use the data here */
SysFreeString(theData[i].filename);
SysFreeString(theData[i].hostname);
}
// Done with the data..
SafeArrayUnaccessData(theArrary->parray);
//Hmmm? Why does calling SafeArrayDestroy() here crash the client
when it releases the pRecInfo?
// And why shouldn't I release theArrary->rRecInfo?
*ret = 0;
TRACE("Finish AddSearchDatabases()\n");
return S_OK;
}
----------------------------------------------------------------------------------------
This is a PRIVATE message. If you are not the intended recipient, please
delete without copying and kindly advise us by e-mail of the mistake in
delivery. NOTE: Regardless of content, this e-mail shall not operate to
bind CSC to any order or other contract unless pursuant to explicit written
agreement or government initiative expressly permitting the use of e-mail
for such purpose.
----------------------------------------------------------------------------------------
----------------------------------------------------------------
Users Guide http://discuss.microsoft.com/archives/mailfaq.html
contains important info. Save time, search the archives at
http://discuss.microsoft.com/archives/index.html .
To unsubscribe, mailto:DCOM-signoff-request
DISCUSS.MICROSOFT.COM
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]