0

I am trying to use a C library in Python using SWIG. This C library passes function results through arguments everywhere. Using the online SWIG manual, I have succeeded in getting an integer function result passed to Python, but I am having a hard time figuring out how to do this for a character string.

This is the essence of my code:

myfunc.c:

#include <myfunc.h>

#include <stdio.h>


int mystr(int inp, char *outstr){
   outstr="aaa";
   printf("%s\n", outstr);
   return(0);
}

myfunc.h:

extern int mystr(int inp, char *outstr);

So basically my question is what the typemap for *outstr should look like.

Thanks in advance.

3
  • 2
    Did you really mean outstr="aaa";? I suspect you meant strcpy(outstr,"aaa");. Commented Jul 22, 2016 at 18:11
  • I guess that I did. Commented Jul 25, 2016 at 6:55
  • In particular outstr="aaa"; wouldn't change the string that the caller passes in. The outstr parameter is treated as a local variable in the function, so outstr="aaa"; just makes the local outstr point to an unnamed, initialized array of 4 characters { 'a', 'a', 'a'. '\0' }. Commented Jul 25, 2016 at 16:15

2 Answers 2

2

Have a look at the SWIG manual 9.3.4 String handling: cstring.i. This provides several typemaps for use with char * arguments.

Probably (assuming you are indeed using strcpy(outstr, "aaa") as mentioned in a comment above) you want in your SWIG interface file, before the function declaration, e.g.:

%include <cstring.i>
%cstring_bounded_output(char* outstr, 1024);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your suggestion. I already spent quite some time looking at the manual, but as I am not a C coder, I find the manual difficult to read and the examples not easy to generalize from.
0

This is how I got it to work, by modifying the example in section 34.9.3 of the SWIG 2.0 manual:

%typemap(in, numinputs=0) char *outstr (char temp) {
   $1 = &temp;
}
%typemap(argout) char *outstr {

    PyObject *o, *o2, *o3;
    o = PyString_FromString($1);
    if ((!$result) || ($result == Py_None)) {
        $result = o;
    } else {
        if (!PyTuple_Check($result)) {
            PyObject *o2 = $result;
            $result = PyTuple_New(1);
            PyTuple_SetItem($result,0,o2);
        }
        o3 = PyTuple_New(1);
        PyTuple_SetItem(o3,0,o);
        o2 = $result;
        $result = PySequence_Concat(o2,o3);
        Py_DECREF(o2);
        Py_DECREF(o3);
    }
}

1 Comment

Your temp is just a single char, so this code will at some point segfault if your outstr is ever longer than 1 char. Otherwise, your code is essentially a simplified version of %cstring_bounded_output.

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.