The problem with your current code is that as soon as you call src_hndl.Free() the pointer is not necessarily valid any more! .NET is allowed to move the memory contents of objects at will unless they are pinned (which is what the first line does). By freeing the GCHandle it is no longer pinned and liable to move/freed as the garbage collector compacts memory. Also, in 64-bit Python, you will need to call ToInt64() instead of ToInt32(). In fact, it may always be reasonable to call ToInt64() since Python's integer type will likely deal with it being 32 or 64-bit automatically.

So all in all:
Jeff


On Fri, May 23, 2014 at 3:34 AM, Dave Cook <daverz@gmail.com> wrote:
(Sorry for screwing up the thread; I messed up my list subscription.
This is a response to
https://mail.python.org/pipermail/pythondotnet/2014-May/001525.html )

Thanks, Jeffrey, that's awesome.  Since the pointer can be directly
accessed, np.frombuffer() can be used to avoid a copy.

src_hndl = GCHandle.Alloc(src, GCHandleType.Pinned)
try:
    src_ptr = src_hndl.AddrOfPinnedObject().ToInt32()
    bufType = ctypes.c_double*len(src)
    cbuf = bufType.from_address(src_ptr)
    dest = np.frombuffer(cbuf, dtype=cbuf._type_)
finally:
    if src_hndl.IsAllocated: src_hndl.Free()

Dave Cook
_________________________________________________
Python.NET mailing list - PythonDotNet@python.org
https://mail.python.org/mailman/listinfo/pythondotnet