On Tue, Oct 14, 2008 at 2:28 PM, Dag Sverre Seljebotn <[EMAIL PROTECTED]> wrote: > Ondrej Certik wrote: >> On Mon, Oct 13, 2008 at 6:33 PM, Dag Sverre Seljebotn >> >> >>> Note that this is non-trivial since any copy made must also not be >>> deallocated, so that iarray_d would have to return a reference which >>> must be held on to for the duration of using the buffer data. >>> >>> If you need to accept ndarrays coming from the user, a better idiom is >>> likely to take a callback function which will be called with the buffer >>> as an argument, or similar -- returning the buffer through a double** >>> (or np.float64_t**) is rather error-prone when it comes to reference >>> counting. >>> >> >> Yeah, I thought pretty much along the same lines. >> >> Basically, I am fine if the function raises an exception on >> noncontiguous arrays and/or copy the array automatically, so that's >> not an issue. >> >> The big problem is with the reference counting, i.e. who is >> reposnsible for freeing the double** memory. Basically, the memory is >> automatically freeed when the numpy array goes out of scope, right? So >> basically, the rule is: either do something with the double** array >> immediatelly (in C/C++) on the fly, or make a copy of it if you need >> it longer. Another option would be to Py_IncRef/DecRef the numpy array >> to make sure the C array is not recycled. >> > Pretty much. To hold a reference, simply assign it to a Cython "object" > variable, don't bother manually reference counting it.
Nice trick, didn't occur to me. > > I think the general rule should be "keep the data in the numpy array for > as long as possible". I must admit that I cannot imagine many situations > where it would be good to store the double* for future reference rather > than the entire Python array object. They're just pointers, it's not > like it is "heavier" to store the ndarray :-) > > I suppose one case is if you have a stateful C library like this: > > clib.set_data(mydata) > clib.perform(...) > clib.release_data() > > and you want to create a 1:1 wrapper in Cython. Yes, in that case you > need to mirror the state info on the Cython-side and store a reference > to the ndarray in the wrapper as well as feeding the pointer to C. This is exactly my case. I am writting a C++ code that operates over double* arrays and I have 1:1 Cython wrapper for the classes. But a nice trick is to hold the reference to the input array in the Cython object in the Cython class --- that could do the job. Ondrej _______________________________________________ Cython-dev mailing list [email protected] http://codespeak.net/mailman/listinfo/cython-dev
