[pypy-dev] Pointer To Member Problem with rctypes

Samuele Pedroni pedronis at strakt.com
Tue Feb 14 14:39:58 CET 2006


Gerald Klix wrote:
> Hi all,
> I have a problem with GcStruct, Struct and Ptr I can not resolve with my 
> own devices.
> 
> After some trial with ctypes running on CPython I came up with the 
> following lowlevel representation for structures:
> 
>     Ptr( GcStruct( "CtypesGcStructure_<ClassName>
>             ( "c_data"
>                     (Struct "C-Data_<ClassName>
>                             *<Fieldefintions>) ) ) )
> 

to access c_data from a  pointer to the surrounding GcStruct,
you want the operation "getsubstruct", not "gefield" which is only for 
Primitive and pointer fields (not substructures), getsubstruct will 
return a pointer correctly.

The low level operations for access are together:

getfield / setfield
getsubstruct (there's no setsubstruct)

getarrayitem / setarrayitem
getarraysubstruct (for array of structs)

getarraysize

and we have a cast_pointer also

> Samuele and Armin helped to implement rtype_getattr and rtype_setattr 
> that delegate all attribute access to the c_data field, by pointing
> out how to implement a helper method called generateCDataAccess:
> 
>     def generateCDataAccess( self, variable, lowLevelOperations ):
>         """
>         Answer the C level data sub structure.
>         """
>         inputargs = [ variable, inputconst( Void, "c_data" ) ]
>         return lowLevelOperations.genop(
>                 "getfield",
>                 inputargs,
>                 # Using Ptr makes the C-compiler barf,
>                 # omitting Ptr leeds to specialisation errors
>                 Ptr( self.c_data_lowleveltype ) )
> 
>     def rtype_setattr( self, highLevelOperation ):
>         c_data = self.generateCDataAccess(
>                 highLevelOperation.inputarg( self, 0 ),
>                 highLevelOperation.llops )
>         inputargs = highLevelOperation.inputargs(
>                     *highLevelOperation.args_r[ :3 ] )
>         inputargs[ 0 ] = c_data
>         print "inputargs:", inputargs
>         print "r_result:", highLevelOperation.r_result
>         highLevelOperation.genop( "setfield", inputargs )
> 
> Obviously generateCDataAccess needs to return a Ptr to the embedded
> C-structure. When I use Ptr as in the example above, I get the following
> traceback:
> 
>     c:\Dokumente und Einstellungen\root\Lokale 
> Einstellungen\Temp\usession-353\testi
>     ng_2\testing_2.c(894) : error C2440: '=': 'pypy_C_Data_tagpoint0' 
> kann nicht in
>     'pypy_C_Data_tagpoint0 *' konvertiert werden
> 
> Which means, that a 'pypy_C_Data_tagpoint0' can not be converted to a
> 'pypy_C_Data_tagpoint0 *'. A brief look at the generated C-source,
> shows that the compiler is right here:
> 
>     struct pypy_CtypesStructure_tagpoint0 
> *pypy_g__py_test_compile_struct(struct pypy_CtypesStructure_tagpoint0 
> *l_p_0, long l_x_1, long l_y_1) {
>             /*void l_v111;*/ /*void l_v112;*/
>             struct pypy_C_Data_tagpoint0 *l_v98;
>             struct pypy_C_Data_tagpoint0 *l_v99;
>             struct pypy_CtypesStructure_tagpoint0 *l_v110;
>             pypy_IncRf_CtypesStructure_tagpoint0(l_p_0);
> 
>         block0:
>             l_v98 = l_p_0->cs_c_data;
>             l_v98->cd_x = l_x_1;
>             l_v99 = l_p_0->cs_c_data;
>             l_v99->cd_y = l_y_1;
>             l_v110 = l_p_0;
>             goto block1;
> 
> 
>         block1:
>             return l_v110;
>      }
> 
> If I ommit the Ptr construction so that, generateCDataAccess is defined 
> as follows:
> 
>     def generateCDataAccess( self, variable, lowLevelOperations ):
>         """
>         Answer the C level data sub structure.
>         """
>         inputargs = [ variable, inputconst( Void, "c_data" ) ]
>         return lowLevelOperations.genop(
>                 "getfield",
>                 inputargs,
>                 self.c_data_lowleveltype )
> 
> I get the following error:
> 
>     [D:\svnwork\work\dist\pypy\rpython\lltypesystem\lltype.py:146]
>     _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> 
>         def _nofield(self, name):
>             raise AttributeError, 'struct %s has no field %r' % 
> (self._name,
>     E                                                            name)
>     >       AttributeError: struct C-Data_tagpoint has no field 'TO'
> 
> This is no surprise at all. The getfield operation obviosly needs a 
> pointer to
> work with.
> 
> So it boils down to the question:
> How can I access the members of an embedded structure?
> Is there a possibility to get the address of substructure, just like
> C's ampersand (&) operator does?
> 
> 
> Any help is welcome.
> 
> Best regards,
> Gerald
> 
> _______________________________________________
> pypy-dev at codespeak.net
> http://codespeak.net/mailman/listinfo/pypy-dev




More information about the Pypy-dev mailing list