You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am passing a 2d array of strings to c++ library.
2d arrays are converted to ndarrays before being placed in safearrays.
Temporary VARIANT objects are created to be put in ndarray:
def _ndarray_to_variant_array(value):
varr = numpy.zeros(value.shape, npsupport.VARIANT_dtype, order='F')
varr.flat = [VARIANT(v) for v in value.flat] <--------------- here
..this temporary variants are then destroyed (confirmed by print statements in tagVARIANT.del).
You would assume that the copies placed in varr are intact, however it looks like their string pointers (BSTR fields) are marked as free as a result.
On the c++ side all data is visible fine until one tries to create any BSTR using SysAllocString: BSTRs in the input are overridden.
e.g. I pass A = [[A00],[A10],[A20],[A30]] (a 2d array of 4x1).
On c++ side I make a copy of it, B = A, B_ij = A_ij; however as I copy B00 = A00, B00 (expectedly) becomes A00 and also A30 incidentally becomes A00, because B00 uses the same address as A30; then B10 = A10, and incidentally A20 becomes A10.
B_ij is obtained by ::SysAllocStringLen(A_ij, SysStringLen(A_ij)), so should be legitimate allocation of memory for new BSTR.
My guess is SysAllocString picks memory allocated for A30 and assumes it is free.
..Back to Py side:
If I comment out _VariantClear in the comptypes/automation.py:
class tagVARIANT(Structure):
class U_VARIANT1(Union):
..
..
def del(self):
if self.b_needsfree:
#_VariantClear(self) <------------------------
..then everything works fine.
Which confirms that memory allocated for strings on the Pythons side is marked as free and reused any time one wants to create BSTR object.
Suprisingly, no problems were noticed when using 1d array.
My guess is memory is still marked as free, but the allocation order is such, that this memory is not overridden.
Also, no problems when passing list or tuple.
(however, if I pass a nested list, it creates a safearray of safearrays instead of 2d safearray of non-safearray variants)
Any thoughts?
The text was updated successfully, but these errors were encountered:
I am passing a 2d array of strings to c++ library.
2d arrays are converted to ndarrays before being placed in safearrays.
Temporary VARIANT objects are created to be put in ndarray:
def _ndarray_to_variant_array(value):
varr = numpy.zeros(value.shape, npsupport.VARIANT_dtype, order='F')
varr.flat = [VARIANT(v) for v in value.flat] <--------------- here
..this temporary variants are then destroyed (confirmed by print statements in tagVARIANT.del).
You would assume that the copies placed in varr are intact, however it looks like their string pointers (BSTR fields) are marked as free as a result.
On the c++ side all data is visible fine until one tries to create any BSTR using SysAllocString: BSTRs in the input are overridden.
e.g. I pass A = [[A00],[A10],[A20],[A30]] (a 2d array of 4x1).
On c++ side I make a copy of it, B = A, B_ij = A_ij; however as I copy B00 = A00, B00 (expectedly) becomes A00 and also A30 incidentally becomes A00, because B00 uses the same address as A30; then B10 = A10, and incidentally A20 becomes A10.
B_ij is obtained by ::SysAllocStringLen(A_ij, SysStringLen(A_ij)), so should be legitimate allocation of memory for new BSTR.
My guess is SysAllocString picks memory allocated for A30 and assumes it is free.
..Back to Py side:
If I comment out _VariantClear in the comptypes/automation.py:
class tagVARIANT(Structure):
class U_VARIANT1(Union):
..
..
def del(self):
if self.b_needsfree:
#_VariantClear(self) <------------------------
..then everything works fine.
Which confirms that memory allocated for strings on the Pythons side is marked as free and reused any time one wants to create BSTR object.
Suprisingly, no problems were noticed when using 1d array.
My guess is memory is still marked as free, but the allocation order is such, that this memory is not overridden.
Also, no problems when passing list or tuple.
(however, if I pass a nested list, it creates a safearray of safearrays instead of 2d safearray of non-safearray variants)
Any thoughts?
The text was updated successfully, but these errors were encountered: