<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
{mso-style-priority:99;
mso-style-link:"Sprechblasentext Zchn";
margin:0cm;
margin-bottom:.0001pt;
font-size:8.0pt;
font-family:"Tahoma","sans-serif";
mso-fareast-language:EN-US;}
span.E-MailFormatvorlage17
{mso-style-type:personal-compose;
font-family:"Calibri","sans-serif";
color:windowtext;}
span.SprechblasentextZchn
{mso-style-name:"Sprechblasentext Zchn";
mso-style-priority:99;
mso-style-link:Sprechblasentext;
font-family:"Tahoma","sans-serif";}
.MsoChpDefault
{mso-style-type:export-only;
mso-fareast-language:EN-US;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="DE" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US">Hi,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">I already posted a related question on the comtypes mailing list but unfortunately Thomas Heller told me that he cannot actively provide support anymore.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">So I'm hoping to get some help here because it might also relate more to ctypes.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">At first, sorry for the long mail but it’s a rather complex issue and I want to provide as much information and context as required.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Heres the problem:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">We wrote a COM server using comtypes which worked well on Win XP. However, on Windows 2008 and Win 7, the same code crashes after calling a specific method that our server provides.
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">By "crashes" I mean the COM client (Tried it with a C++ and python client) receives a COMError:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">_ctypes.COMError: (-2147417851, 'Ausnahmefehler des Servers.', (None, None, None, 0, None))<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">The Server does *<b>not</b>* throw any exceptions as far as I can see and keeps on running. I added some printf debugging in comtypes but everything seems fine and ends up calling some win32api functions after message
dispatching is done.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">Every time this happens, in the windows application event log, there is an entry saying "python.exe" was the offending application, "ntdll.dll" was the offending module. I also set up windows debugging modules with shows
the following stack trace (just first few lines at the top):<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">ntdll!RtlpLowFragHeapFree+0x31 (FPO: [Non-Fpo])<o:p></o:p></span></p>
<p class="MsoNormal">01 0021ed04 76f49c46 00390000 00000000 029e76e0 ntdll!RtlFreeHeap+0x101
<o:p></o:p></p>
<p class="MsoNormal">02 0021ed18 7718afbd 00390000 00000000 029e76e8 kernel32!HeapFree+0x14
<o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-GB">03 0021ed2c 7718afd9 7725f6f8 029e76e8 0021ed54
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">ole32!CRetailMalloc_Free+0x1c (FPO: [Non-Fpo])<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">04 0021ed3c 75be6efc 029e76e8 01f685fe 0021edcc ole32!CoTaskMemFree+0x13<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Since the problem arises reproducibly when calling one method the has a pointer to an array as input and output, I believe this is some kind of memory issue (which also the stack trace suggests) that was probably just
not recognized/caught by WinXP before but now shows up in more recent windows versions.
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">My assumption is, that either I need to actively allocate or deallocate memory for in/out parameters.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">This is the method signature of the method that our server provides and that crashes:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">IOPCItemMgt::ValidateItems<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">HRESULT ValidateItems(<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">[in] DWORD dwCount,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">[in, size_is(dwCount)] OPCITEMDEF * pItemArray,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">[in] BOOL bBlobUpdate,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">[out, size_is(,dwCount)] OPCITEMRESULT ** ppValidationResults,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">[out, size_is(,dwCount)] HRESULT ** ppErrors<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">); <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">Assume that this is the signature in python comtypes server:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"> def ValidateItems(self, count, p_item_array, update_blob):<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">and this is the ctypes structure which should be returned in "</span><span lang="EN-GB">
</span><span lang="EN-GB">ppValidationResults ":<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"> OpcDa.tagOPCITEMRESULT<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">How would I create these structures (especially ppValidationResults), its contents and the pointers so that I would not create any memory issues, null pointers or whatsoever?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">My implementation creates a few items by calling<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"> validation_result = OpcDa.tagOPCITEMRESULT()
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">filling in the contents with e.g.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"> validation_result.hServer = server_item_handle<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">adding it to a list<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"> validation_results.append(validation_result)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">then converting it to a pointer to an array with a helper function:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"> def p_list(items):<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"> c_items = (type(items[0])*len(items))(*items)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"> p_items = cast(c_items, POINTER(type(items[0])))<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"> return p_items<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"> <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"> (…)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"> p_validation_results = p_list(validation_results)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">doing the same with "errors" and then returning it:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"> return p_validation_results, p_errors<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">Is that correct?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">Do I have to keep references to the list, the pointer or the item strcuture objects to avoid them beeing garbage collected?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB">Thanks a lot!<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
</div>
</body>
</html>