logo       

Re: RE: Re: Problems with nested structures: msg#00028

python.ctypes

Subject: Re: RE: Re: Problems with nested structures

Stefan Schukat <SSchukat@xxxxxxxxx> writes:

>> -----Original Message-----
>> From: ctypes-users-admin@xxxxxxxxxxxxxxxxxxxxx
>> [mailto:ctypes-users-admin@xxxxxxxxxxxxxxxxxxxxx]On Behalf Of Thomas
>> Heller
>> Sent: Tuesday, October 19, 2004 1:25 PM
>> To: ctypes-users@xxxxxxxxxxxxxxxxxxxxx
>> Subject: [ctypes-users] Re: Problems with nested structures
>>
>>
>> Stefan Schukat <SSchukat@xxxxxxxxx> writes:
>>
>> > Hello,
>> >
>> > I have a problem getting nested structures from a C-API interface.
>> > The call succeeds but all members in the nested elements are empty.
>> >
>> > Could my definition of the call be wrong or is there any
>> restriction in
>> > C-Types that
>> > structures with structures with union are not transported ?
>> >
>> > I'm working with ctypes 0.6.3 and Python 2.2.1.
>> >
>> > Thanks
>> >
>> > Stefan
>> >
>> >
>> >
>> > Background:
>> >
>> > The call I want to wrap is defined as
>> >
>> > int GetData( unsigned char** pRecvBuffer, unsigned short* pObjNum);
>> >
>> > where the first element is a Structure with nested
>> structures in C, e.g.
>> > sample C-Code
>> >
>> > unsigned char* RecvBuffer;
>> > WORD nObj;
>> > MyStruct* Data;
>> > iRet = GetData(&RecvBuffer, &nObj);
>> >
>> > if (iRet && nObj>0)
>> > {
>> > Data = (MyStruct*)(RecvBuffer);
>> >
>> > where the structure is defined as:
>> >
>> > typedef struct {
>> > unsigned char Length;
>> > LogStruct Log;
>> > } MyStruct;
>> >
>> > with:
>> >
>> > typedef struct {
>> > unsigned char Length;
>> > unsigned char Data[8];
>> > IDUnion ID;
>> > } LogStruct;
>> >
>> > with:
>> >
>> > typedef union
>> > {
>> > unsigned long Dword;
>> > unsigned short Word[2];
>> > unsigned char Byte[4];
>> > } IDUnion;
>> >
>> >
>> > and I wrapped it with:
>> >
>> > class MyStruct(ctypes.Structure):
>> > _fields_ = [
>> > ("Length", ctypes.c_ubyte),
>> > ("Log", LogStruct),
>> > ]
>> >
>> >
>> > class LogStruct(ctypes.Structure):
>> > _fields_ = [("Length", ctypes.c_ubyte),
>> > ("Data", ctypes.c_ubyte * 8),
>> > ("ID", IDUnion ),
>> > ]
>> >
>> > class IDUnion(ctypes.Union):
>> > _fields_ = [("Dword", ctypes.c_ulong),
>> > ("Word", ctypes.c_ushort * 2),
>> > ("Byte", ctypes.c_ubyte * 4)
>> > ]
>> >
>> > def GetData(self):
>> > LocalpRecvBuffer = ctypes.pointer(MyStruct())
>> > LocalpObjNum = ctypes.c_ushort()
>> > self._Handle.GetData(ctypes.byref(LocalpRecvBuffer),
>> ctypes.byref(LocalpObjNum))
>> > if LocalpObjNum.value > 0:
>> > return LocalpRecvBuffer.contents, LocalpObjNum.value
>> > else:
>> > return None, 0
>> >
>> > All elements of Logstruct and IDUnion aree still empty
>> after the call.
>>
>> I think the problem is that you pass a pointer to MyStruct with byref.
>> This should work:
>>
>> def GetData(self):
>> LocalpRecvBuffer = MyStruct()
>> LocalpObjNum = ctypes.c_ushort()
>> self._Handle.GetData(ctypes.byref(LocalpRecvBuffer),
>> ctypes.byref(LocalpObjNum))
>> if LocalpObjNum.value > 0:
>> return LocalpRecvBuffer.contents, LocalpObjNum.value
>> else:
>> return None, 0
>>
>> Thomas
>>
> Hello,
>
> I tried it with your suggestion, but still the subelements are empty.
> The thing to bother about is the second level of indirection of in the call
>
> int GetData( unsigned char** pRecvBuffer, unsigned short* pObjNum);
> ^^

> Thats why I introduced the byref pointer. I access memory that the
> called function allocated. So I don't have to allocate memory in
> advance as in instaniating MyStruct before the call. Do you think the
> cast function you introduced lately would help in this situation ?

No, the cast is not needed. And I missed the double stars in 'unsigned char **',
sorry for that.
So, you need to create a (NULL) pointer to your MyStruct, and the
function fills it?

def GetData(self):
pBuf = POINTER(MyStruct)() # create a NULL pointer to MyStruct
LocalpObjNum = ctypes.c_ushort()
self._Handle.GetData(ctypes.byref(pBuf), ctypes.byref(LocalpObjNum))
if LocalpObjNum.value > 0:
return pBuf[0], LocaloObjNum.value
else:
return None, 0

Hm, does this behave different than the code you first posted? It
should, imo.

Thomas



-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise