Using a SWIG-generated interface it’s straightforward to assign variables of type char * from a Python script to a C variable: the char * datatype is assumed to be a NULL terminated ASCII string and mapped accordingly. The situation is a little different for variables of type char **, commonly used for arrays of pointers to strings.
The SWIG documentation has a very useful typedef for converting a Python list to a char **. However, I found that it was fine for passing in lists of strings as arguments to functions, but not for simple variable assignments. For example I found that the following example didn’t work:
my_charpp = ["foo", "bar"]
…where my_charpp is declared in C as having type char **. After some experimentation with the typemap and a wrapper function, I found that I could achieve what I wanted by modifying the typemap, to only work on a named pointer, and providing a helper function to do the assignment.
Typemaps:
%typemap(in) (char **pylist){
...
}
%typemap(freearg) char **pylist {
...
}
Helper functions:
%inline %{
char **set_list(char **pylist){
int i = 0;
char **l;
int temp = 0;
while(pylist[i] != NULL)
i++;
l = ntg_malloc(i * sizeof(char *));
while(i--){
temp = strlen(pylist[i]);
l[i] = ntg_malloc((temp + 1) * sizeof(char));
strcpy(l[i], pylist[i]);
}
return l;
}
void print_list(char **mlist, int n_items){
while(n_items--)
printf("%s\n", mlist[n_items]);
}
%}
So from my Python script, I can do the following:
mylist = ["foo", "bar"]
my_charpp = set_list(mylist)
print_list(my_charpp, 2)
…and it works like a charm! Don’t forget that if you are going to use this code, you need to ‘manually’ free the out-of-place memory allocated by set_list().