Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.
Getting a Python exception (access violation) after running back-to-back function calls with the exact same parameters. Using pdb, I've captured traces of both the calls for comparison.
Logged In: YES
File Added: run2.log
Logged In: YES
Mark, I'm afraid there is not enough information in the traces you have posted, but maybe I'm only too lazy to stare at them for a long time.
It looks like that the freeing of some resources (safearrays? or strings contained in safearrays?) is causing the problem - I am not at all sure that the safearray code is bug free.
Can you in any way make more information available?
Thomas, I'd be happy to provide more information -- can you tell me where to begin?
I've been going over the pdb trace and it occurred to me that perhaps the call to _free(self) on line 861 in __init__.py (class BSTR.__ctypes_from_outparam_) might be to blame?
I commented this line out locally on my system and I'm no longer hitting the exception.
Could this be the bug?
> Could this be the bug?
No. Your code will probably work better when you make this patch, but BSTR strings received as [out] parameters will no longer be freed so there will be memory leaks.
> Thomas, I'd be happy to provide more information -- can you tell me where to begin?
Best would be if you can give me the code and the COM object that shows the problem so that I can reproduce and debug it on my own machine.
If this is not possible, you should at least provide a code snippet that shows a little context around your method call, the IDL definition (for the method that you call) or the type library for the COM object. Plus any other information that might be useful.
Something like that...
Here is the comtypes generated Python code for the method I'm calling:
COMMETHOD([dispid(16), helpstring(u'method ReadState')], HRESULT, 'ReadState',
( ['in'], c_ulong, 'c_ulDeviceIndex' ),
( ['in'], BSTR, 'c_bstrStateSpec' ),
( ['out'], POINTER(BSTR), 'pbstrBitfieldFormat' ),
( ['out'], POINTER(VARIANT), 'pvData' )),
Also, Thomas, could you please explain to me why it is necessary to call _free(self) twice inside of the BSTR class? (see below)
"The windows BSTR data type"
_type_ = "X"
return "%s(%r)" % (self.__class__.__name__, self.value)
def __ctypes_from_outparam__(self, _free=windll.oleaut32.SysFreeString):
result = self.value
_free(self) # <--- here
def __del__(self, _free=windll.oleaut32.SysFreeString):
"""If we own the memory, call SysFreeString to free it."""
if not self._b_base_:
_free(self) # <--- and here