<div dir="ltr">One more wrinkle, of course!<div>This code you suggested works fine in Python3:</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"><span style="font-size:12.8px">  b = bytes(a)  # where "a" is a VTK array object</span></blockquote><div><br></div><div>Unfortunately, it doesn't work in Python 2.7 - it's returning the equivalent of str(a), which is info about the object:</div><div>'vtkUnsignedCharArray (00000000124BC8A0)\n  Debug: Off\n  Modified Time: 274789\n ....'</div><div><br></div><div>So I'm going to switch to this:</div><div>b = memoryview(a).tobytes()</div><div><br></div><div>which will work in Python 2.7 and above, and should result in just one copy.</div><div>Regards,</div><div>Aron</div><div> </div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Aug 6, 2017 at 12:36 PM, 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Thank you for your suggestions and help. I got the ctypes method working in my code, then discovered that the websocket library I am using requires a 'bytes' object exactly - a bytes-like object won't do. So I am stuck doing a copy, I think.<div><br></div><div>Thanks again!</div><span class="HOEnZb"><font color="#888888"><div>Aron</div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Aug 4, 2017 at 12:22 PM, David Gobbi <span dir="ltr"><<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>On Fri, Aug 4, 2017 at 10:02 AM, David Gobbi <span dir="ltr"><<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>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="m_-6439547199521278697m_-5974922595083807436m_-8526180513467945208gmail-"><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/vtkPVWebAppl<wbr>ication.cxx:</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div>vtkUnsignedCharArray* vtkPVWebApplication::StillRend<wbr>er(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::StillRend<wbr>erToString(), 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></span><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><span><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></span><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></div></div></blockquote><div><br></div><div><br></div></span><div>I just remembered something else.  The Python 'ctypes' module is another way of doing zerocopy.  Here is some example code:</div><div><br></div><div>c_type = ctypes.c_char*n # this means 'char [n]' c-style array</div><div>c_array = c_type.from_buffer(a) # where 'a' is a VTK array</div><div><br></div><div>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.  </div><span class="m_-6439547199521278697HOEnZb"><font color="#888888"><div><br></div><div> - David</div><div> </div></font></span></div></div></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>