Your example C++ code isn't quite legal (it looks more like Java!), but once I fixed that and added something real for process
to do I was able to wrap it as you hoped.
Compared to my previous answer the main change is that the length gets read from inside the class, rather than being the result of calling a method on a container. This is kind of ugly, because I had to hardcode the name of the C++ 'this' object, $self
referred to the Python object. Due to that I made the typemap only get applied in restricted circumstances where we're sure it's legal and correct.
So my final interface file ended up looking like:
%module test
%typemap(out) char *DataHolder::BinaryData {
Py_buffer *buf=(Py_buffer*)malloc(sizeof *buf);
if (PyBuffer_FillInfo(buf, NULL, $1, arg1->Length, true, PyBUF_ND)) {
// Error, handle
}
$result = PyMemoryView_FromBuffer(buf);
}
%inline %{
class DataHolder
{
public:
char* BinaryData;
long Length;
};
class MyProcessor
{
public:
int process(DataHolder& holder)
{
static char val[] = "Hello\0Binary\0World\n!";
holder.BinaryData = val;
holder.Length = sizeof val;
return 0;
}
};
%}
Which I tested with:
from test import *
proc = MyProcessor()
holder = DataHolder()
proc.process(holder)
data = holder.BinaryData
print(repr(data))
print(data.tobytes())
I targeted Python3 here, but the exact same code should work for Python 2.7. When compiled and run this gave:
swig2.0 -c++ -Wall -py3 -python test.i
g++ -Wall -shared -o _test.so test_wrap.cxx -I/usr/include/python3.4
python3 run.py
<memory at 0xb7271f9c>
b'Hello\x00Binary\x00World\n!\x00'