Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variant pointers to BSRT marked as free before being passed to c++ side #164

Closed
Antonm5012 opened this issue Aug 24, 2018 · 2 comments
Closed

Comments

@Antonm5012
Copy link

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?

@Antonm5012
Copy link
Author

Solved by creating a storage for variants: input values converted to variants are saved in the storage and destroyed only after the function call

@junkmd
Copy link
Collaborator

junkmd commented Dec 6, 2022

@Antonm5012

If the issue remains, please re-open.

—-
This may be a clue to resolving #80 and #347.

@junkmd junkmd closed this as completed Dec 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants