[vtk-developers] VTK python wrapping - returning binary buffer to python?
David Gobbi
david.gobbi at gmail.com
Fri Aug 4 12:22:51 EDT 2017
On Fri, Aug 4, 2017 at 10:02 AM, David Gobbi <david.gobbi at gmail.com> wrote:
> On Fri, Aug 4, 2017 at 9:08 AM, Aron Helser <aron.helser at kitware.com>
> wrote:
>
>>
>> Sure thing. And as I trace the code more carefully, I found at least part
>> of the issue.
>>
>> I miss-spoke - the method in question is in ParaView, an override of a
>> method in VTK:
>>
>> ParaView/Web/Core/vtkPVWebApplication.cxx:
>> vtkUnsignedCharArray* vtkPVWebApplication::StillRender(vtkSMViewProxy*
>> view, int quality)
>>
>> However, that method is wrapped in const char*
>> vtkPVWebApplication::StillRenderToString(), which does this:
>>
>>
>> return reinterpret_cast<char*>(array->GetPointer(0));
>>
>> So that's where the 'char *' to python 'str' conversion happens.
>>
>
> Yes, python will interpret a returned "char *" as a c-style string. One
> way to avoid this is to return an std::string, but std::string isn't useful
> when you're trying to do a zero-copy operation.
>
>
> If I avoid that wrapper and return vtkUnsignedCharArray* directly, can I
>> get a python 'bytes' object out of it in the Python code without copying?
>>
>
> Yes. In Python, the vtkUnsignedCharArray (and all other array types)
> support the Python buffer interface. That's a feature that Berk added to
> the wrappers a few years back.
>
> So if you were (hypothetically) using numpy, you could use
> numpy.frombuffer() to interpret the VTK array as a numpy array. This is a
> perfect zerocopy operation.
>
> The Python builtins, however, are more cautious about zerocopy than VTK or
> numpy. So if you were to simply do this, you'd get a copy:
>
> b = bytes(a) # where "a" is a VTK array object
>
> The Python "bytes" object is supposed to own its own memory, it wasn't
> designed to share. Even the numpy .tostring() and .tobytes() methods
> produce copies.
>
> However, I suspect that you don't have to convert the array to bytes
> anyway. Just pass the VTK array object to whatever method you were
> planning to pass the 'bytes' object to, and it will probably work fine.
> Many methods that take 'bytes' will actually take any object that provides
> a buffer interface, and that includes numpy arrays and VTK arrays.
>
I just remembered something else. The Python 'ctypes' module is another
way of doing zerocopy. Here is some example code:
c_type = ctypes.c_char*n # this means 'char [n]' c-style array
c_array = c_type.from_buffer(a) # where 'a' is a VTK array
So c_array is now shares memory with the VTK array. And you can use
'c_array.raw' to convert it into 'bytes', but like all the other methods we
have seen that produce 'bytes', it produces a copy.
- David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtk-developers/attachments/20170804/9bf729a3/attachment.html>
More information about the vtk-developers
mailing list