4

I have a C-function that allocates memory at the address passed to and is accessed via Python. The pointer contents does contain an array of structs in the C code, but I am unable to get ctypes to access the array properly beyond the 0th element. How can I get the proper memory offset to be able to access the non-zero elements? Python's ctypes.memset is complaining about TypeErrors if I try to use their ctypes.memset function.

typedef struct td_Group
{
    unsigned int group_id;
    char groupname[256];
    char date_created[32];
    char date_modified[32];
    unsigned int user_modified;
    unsigned int user_created;
} Group;

int getGroups(LIBmanager * handler, Group ** unallocatedPointer);

############# python code below: 
class Group(Structure):
    _fields_ = [("group_id", c_uint),
                ("groupname", c_char*256),
                ("date_created", c_char*32),
                ("date_modified", c_char*32),
                ("user_modified", c_uint),
                ("user_created", c_uint)]


myGroups = c_void_p()
count = libnativetest.getGroups( nativePointer, byref(myGroups) )
casted = cast( myGroups, POINTER(Group*count) )
for x in range(0,count):
    theGroup = cast( casted[x], POINTER(Group) )
    # this only works for the first entry in the array:
    print "~~~~~~~~~~" + theGroup.contents.groupname

Related: Access c_char_p_Array_256 in Python using ctypes

2
  • What error are you getting? Please add the entire traceback. Commented Nov 30, 2011 at 0:55
  • 1
    @yak: When one is playing around with ctypes, tracebacks are a privilege not always available. If you step out of the line, the norm is the Python interpreter ending up in a segfault Commented Nov 30, 2011 at 2:09

2 Answers 2

4

D Hess put me in the right direction; The solution was:

GroupArray = POINTER(Group * count)
group_array = GroupArray.from_address(addressof(myGroups))
for x in range(0,count):
    print "~~~~~~~~~~" + group_array.contents[x].groupname
Sign up to request clarification or add additional context in comments.

Comments

3

First create a new type which is an array of Group:

GroupArray = Group * count

Then create an instance of a GroupArray this way:

group_array = GroupArray.from_address(myGroups.value)

Then your loop would work like this:

for x in range(0,count):
    print "~~~~~~~~~~" + group_array[x].groupname

2 Comments

Unfortunately, that is printing garbage characters. Note that myGroups is a pointer to the first element of the array (a Group*), not a Group**. The call to libnativetest.getGroups is passing the address of myGroups, which is making it a Group**.
Oops, you are correct. That's a bug - try the fix I put in. Use myGroups.value instead of addressof(myGroups).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.