Python using ctypes to pass a char * array and populate results
Question: I'm trying to use ctypes to create a char * array in python to be passed to a
library for populating with strings. I'm expecting 4 strings back no more than
7 characters in length each.

My py code looks like this

**testlib.py**

    
    
    from ctypes import *
    primesmile = CDLL("/primesmile/lib.so")
    
    getAllNodeNames = primesmile.getAllNodeNames
    getAllNodeNames.argtypes = [POINTER(c_char_p)]
    results = (c_char_p * 4)(addressof(create_string_buffer(7)))
    err = getAllNodeNames(results)
    

**lib.cpp**

    
    
    void getAllNodeNames(char **array){
        DSL_idArray nodes; //this object returns const char * when iterated over
        network.GetAllNodeIds(nodes);
        for(int i = 0; i < (nodes.NumItems()); i++){
        strcpy(array[i],nodes[i]);
        }
    }
    

I keep getting segmentation faults when I try to run this code. I've created a
test from C that works perfectly but in Python I must be setting up the
pointer array incorrectly or something. It seems to get to the second node in
the loop and then have a problem as I've seen from spitting out data into the
command line. Any insight would be much appreciated.


Answer: The following code works:

test.py:

    
    
    import ctypes
    lib = ctypes.CDLL("./libtest.so")
    string_buffers = [ctypes.create_string_buffer(8) for i in range(4)]
    pointers = (ctypes.c_char_p*4)(*map(ctypes.addressof, string_buffers))
    lib.test(pointers)
    results = [s.value for s in string_buffers]
    print results
    

test.c (compiled to libtest.so with `gcc test.c -o libtest.so -shared -fPIC`):

    
    
    #include <string.h>
    void test(char **strings) {
        strcpy(strings[0],"this");
        strcpy(strings[1],"is");
        strcpy(strings[2],"a");
        strcpy(strings[3],"test!");
    }
    

As Aya said, you should make sure there is room for the terminating zero. But
I think your main problem was that the string buffer was garbage collected or
something similar, as there was no direct reference to it anymore. Or
something else is causing trouble in the creation process of the string
buffers when no references are stored for them. For example this results in
four times the same address instead of different addresses:

    
    
    import ctypes
    pointers = [ctypes.addressof(ctypes.create_string_buffer(8)) for i in range(4)]
    print pointers
    

