|
From: William S F. <ws...@fu...> - 2011-08-05 06:40:23
|
On 04/08/11 13:23, Marcello Vitaletti wrote:
> I am using SWIG 1.3.40 for wrapping C++ code to Python ('swig -c++
> -python') on RHEL 6.1
>
> In the C++ code, a wrapped class - say Foo - declares an attribute 'ptr'
> as 'unsigned char * ptr' .
> This one I cannot change (it is code generated by yet another tool)
>
> The SWIG generated Foo Python class includes set/get methods for the
> 'ptr' attribute as for all others.
>
> In the actual use of this code I need (from Python)
> - to allocate an area and fill it with some binary content
> - create an instance of the Foo class
> - set the 'ptr' attribute in this object in a way which causes the
> wrapped C++ object to get an 'unsigned char *' pointer to the above area
>
> Having read the SWIG documentation, and wishing to avoid typemaps, I
> tried to get away with malloc(), and memmove() functions to fill-in a
> buffer of unsigned bytes.
> I asked SWIG to generate allocators for unsigned char, namely specifying
> the following in the input file
>
> <mymodule.i>
> %include cmalloc.i
>
> %allocators(unsigned char, uchar)
>
> The initial task in the Python exploiting code was to allocate an array
> with binary content and create an instance of Foo, which I did as
> follows without problems
>
> <Python code>
> import mymodule
> from array import array
> a = array('B', [(i % 256) for i in range(1024)]
> b = mymodule.Foo()
>
> The second task I would like to accomplish as follows
>
> blob = mymodule.malloc_uchar(1024)
> mymodule.memmove(blob, a.tostring(), 1024);
> b.ptr = blob
> ... do some work with b ...
> mymodule.free_uchar(blob)
>
> Unfortunately, the memmove() function fails with errors: >>> TypeError:
> in method 'memmove', argument 2 of type 'void const *'
>
> It seems I am stuck here because of memmove() requiring a 'void const *'
> type for its second argument.
> This is different from what is in the 1.3 doc manual at 8.2.4 (pag 110)
> where the 2nd arg is said to be 'char *',
> BTW (the manual also declares memmove to take 2 args while it requires
> 3, but that was also reported by other users...)
>
The function is wrapped as if it had two parameters, with the 2nd a
string, even though the underlying implementation calls the C library 3
parameter memmove. I've updated the docs for the next release to remove
this confusion.
> Is there another way to fill the blob area with the content of array a?
>
> Any help will be greatly appreciated (Anybody posting a reply on this
> forum, pls give me also an email alert)
This is how memmove can be used from Python:
%module example
%include <cmalloc.i>
%include <cdata.i>
%allocators(unsigned char, uchar)
%inline %{
void show(void *mem, size_t len) {
char *ptr = (char *)mem;
printf("memory contents: ");
for (size_t i=0; i<len; ++i)
printf("%x ", ptr[i]);
printf("\n");
}
%}
And using it in action:
>>> import example
>>> from array import array
>>> blob = example.malloc_uchar(1024)
>>> a = array('B', [0, 1, 2, 3, 4])
>>> s = a.tostring()
>>> example.memmove(blob, s);
>>> example.show(blob, len(s))
memory contents: 0 1 2 3 4
>>>
William
|