<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Aug 4, 2017 at 9:08 AM, Aron Helser <span dir="ltr"><<a href="mailto:aron.helser@kitware.com" target="_blank">aron.helser@kitware.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="gmail-"><div><br></div></span><div>Sure thing. And as I trace the code more carefully, I found at least part of the issue. </div><div><br></div><div>I miss-spoke - the method in question is in ParaView, an override of a method in VTK:</div><div><br></div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div>ParaView/Web/Core/<wbr>vtkPVWebApplication.cxx:</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div>vtkUnsignedCharArray* vtkPVWebApplication::<wbr>StillRender(vtkSMViewProxy* view, int quality)</div></div><div><br></div></div></div></blockquote><div class="gmail_extra"><div class="gmail_quote"><div>However, that method is wrapped in const char* vtkPVWebApplication::<wbr>StillRenderToString(), which does this:</div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>return reinterpret_cast<char*>(array-<wbr>>GetPointer(0));<br></div><div><br></div></div></div></blockquote><div class="gmail_extra"><div class="gmail_quote"><div>So that's where the 'char *' to python 'str' conversion happens.</div></div></div></div></blockquote><div><br></div><div>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.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>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?</div></div></div></div></blockquote><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>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:</div><div><br></div><div>  b = bytes(a)  # where "a" is a VTK array object</div><div><br></div><div>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.<br></div><div><br></div><div>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.</div><div><br></div><div> - David</div></div></div></div>