Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a list of strings to from python/ctypes to C function expecting char **

Tags:

python

c

ctypes

I have a C function which expects a list \0 terminated strings as input:

void external_C( int length , const char ** string_list) { 
   // Inspect the content of string_list - but not modify it.
} 

From python (with ctypes) I would like to call this function based on a list of python strings:

def call_c( string_list ):
    lib.external_C( ?? )

call_c( ["String1" , "String2" , "The last string"])

Any tips on how to build up the datastructure on the python side? Observe that I guarantee that the C function will NOT alter content of the strings in string_list.

Regards

joakim

like image 847
Joakim Hove Avatar asked Aug 16 '10 15:08

Joakim Hove


3 Answers

def call_c(L):     arr = (ctypes.c_char_p * len(L))()     arr[:] = L     lib.external_C(len(L), arr) 
like image 184
habnabit Avatar answered Sep 24 '22 10:09

habnabit


Thank you very much; that worked like charm. I also did an alternative variation like this:

def call_c( L ):     arr = (ctypes.c_char_p * (len(L) + 1))()     arr[:-1] = L     arr[ len(L) ] = None     lib.external_C( arr ) 

And then in C-function I iterated through the (char **) list until I found a NULL.

like image 32
user422005 Avatar answered Sep 22 '22 10:09

user422005


Using ctypes

create list of expiries( strings)

expiries = ["1M", "2M", "3M", "6M","9M", "1Y", "2Y", "3Y","4Y", "5Y", "6Y", "7Y","8Y", "9Y", "10Y", "11Y","12Y", "15Y", "20Y", "25Y", "30Y"]

Logic to send string array

convert strings array to bytes array by looping in the array

 expiries_bytes = []
    for i in range(len(expiries)):
        expiries_bytes.append(bytes(expiries[i], 'utf-8'))

Logic ctypes to initiate a pointer with a length of array

expiries_array = (ctypes.c_char_p * (len(expiries_bytes)+1))()

assigning the byte array into the pointer

expiries_array[:-1] = expiries_bytes
like image 25
Mandeep Singh Avatar answered Sep 22 '22 10:09

Mandeep Singh