|
From: Marcello V. <mar...@it...> - 2011-08-05 08:46:20
|
William, learning from your example code, I verified that a simple pointer
cast does the work, namely
%inline %{
void * charptr2voidptr(char *charptr) {
return (void *)charptr;
}
%}
I use the above function to cast a string when passing it as 2nd arg to
memmove() and it works
from array import array
a = array('B', [(i % 256) for i in range(1024)])
...
blob = mymodule.malloc_uchar(1024)
mymodule.memmove(blob, mymodule.charptr2voidptr(a.tostring()), 1024);
...
mymodule.free_uchar(blob)
...
Thanks for your help.
Marcello
___________________________________________
Marcello Vitaletti - mar...@it...
From:
Marcello Vitaletti/Italy/IBM@IBMIT
To:
swi...@li...
Cc:
William Fulton <wi...@fu...>, William S Fulton
<ws...@fu...>
Date:
08/05/2011 09:46 AM
Subject:
Re: [Swig-user] How to set attribute from Python to a SWIG wrapped C++
class expecting unsigned char*
William, thanks for your answer. However I see that my SWIG installation
(RHEL 6.1, x64, swig 1.3.40) expands the a 3 arg function for memmove in
the C++ wrapper(see below). This one fails when I call it from Python with
2 args only. When the 3rd arg is given and 2nd arg is the python string as
in your example the call fails validation of the 2nd arg reporting that it
must be a void *
Should I move to a newer version of SWIG (2.0) ? Or is there some way to
work-around on this one? Thanks a lot!
Marcello
___________________________________________
Marcello Vitaletti - mar...@it...
================== memmove Python START =======================
def memmove(*args):
return _educws.memmove(*args)
memmove = _educws.memmove
================== memmove Python END =======================
================== memmove C++ START =======================
SWIGINTERN PyObject *_wrap_memmove(PyObject *SWIGUNUSEDPARM(self),
PyObject *args) {
PyObject *resultobj = 0;
void *arg1 = (void *) 0 ;
void *arg2 = (void *) 0 ;
size_t arg3 ;
int res1 ;
int res2 ;
size_t val3 ;
int ecode3 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"OOO:memmove",&obj0,&obj1,&obj2))
SWIG_fail;
res1 = SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&arg1), 0, 0);
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "memmove" "',
argument " "1"" of type '" "void *""'");
}
res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0);
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "memmove" "',
argument " "2"" of type '" "void const *""'");
}
ecode3 = SWIG_AsVal_size_t(obj2, &val3);
if (!SWIG_IsOK(ecode3)) {
SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "memmove" "',
argument " "3"" of type '" "size_t""'");
}
arg3 = static_cast< size_t >(val3);
memmove(arg1,(void const *)arg2,arg3);
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
}
================== memmove C++ END =======================
From:
William S Fulton <ws...@fu...>
To:
Marcello Vitaletti/Italy/IBM@IBMIT
Cc:
swi...@li...
Date:
08/05/2011 08:39 AM
Subject:
Re: [Swig-user] How to set attribute from Python to a SWIG wrapped C++
class expecting unsigned char*
Sent by:
William Fulton <wi...@fu...>
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
IBM Italia S.p.A.
Sede Legale: Circonvallazione Idroscalo - 20090 Segrate (MI)
Cap. Soc. euro 384.747.048,00
C. F. e Reg. Imprese MI 01442240030 - Partita IVA 10914660153
Società soggetta all?attività di direzione e coordinamento di
International Business Machines Corporation
(Salvo che sia diversamente indicato sopra / Unless stated otherwise
above)
------------------------------------------------------------------------------
BlackBerry® DevCon Americas, Oct. 18-20, San Francisco, CA
The must-attend event for mobile developers. Connect with experts.
Get tools for creating Super Apps. See the latest technologies.
Sessions, hands-on labs, demos & much more. Register early & save!
http://p.sf.net/sfu/rim-blackberry-1
_______________________________________________
Swig-user mailing list
Swi...@li...
https://lists.sourceforge.net/lists/listinfo/swig-user
IBM Italia S.p.A.
Sede Legale: Circonvallazione Idroscalo - 20090 Segrate (MI)
Cap. Soc. euro 384.747.048,00
C. F. e Reg. Imprese MI 01442240030 - Partita IVA 10914660153
Società soggetta all?attività di direzione e coordinamento di
International Business Machines Corporation
(Salvo che sia diversamente indicato sopra / Unless stated otherwise
above) |