Reputation: 1641
I am using SWIG to wrap the following C interface to access it from Python:
void some_method(char **output, int paramA, const char *paramB, int paramC);
The implementation in C allocates memory at runtime using malloc() to the pointer *output. The other parameters are read-only and convey additional information needed by the method.
What should the corresponding SWIG interface file look like?
This case is very simple if I passed only the 'output' parameter which is dynamically allocated in C, and not the other parameters. i.e. If my C interface was the following and its implementation is example.c (say):
void some_method(char **output);
Then the SWIG interface file is simple, as explained in this stackoverflow thread:
%module example
%include<cstring.i>
%cstring_output_allocate(char **output, free(*$1));
%{
extern void some_method(char **output);
%}
%include example.c
The above does not work with multiple parameters. How can one pass multiple parameters, as well as allow dynamic allocation for one of the parameters (in this case 'output' parameter).
Upvotes: 1
Views: 1190
Reputation: 178179
%cstring_output_allocate
does work with multiple parameters. It declares "If you see char **output
as a parameter to any method, hide the parameter and return it as an additional output.
Here's an example. I declare two methods: one that returns a value and one that doesn't. Note in the output how the output
parameter is not passed, but it's result is returned as an additional return value.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void some_method(char **output, int paramA, const char *paramB, int paramC)
{
*output = malloc(paramA);
sprintf_s(*output,paramA,"%s_%d",paramB,paramC);
}
int some_method2(char **output, int paramA, const char *paramB, int paramC)
{
*output = malloc(paramA);
sprintf_s(*output,paramA,"%s_%d",paramB,paramC);
return strlen(*output);
}
void some_method(char **output, int paramA, const char *paramB, int paramC);
int some_method2(char **output, int paramA, const char *paramB, int paramC);
%module x
%begin %{
#pragma warning(disable:4100 4127 4211 4706)
%}
%{
#include "x.h"
%}
%include<cstring.i>
%cstring_output_allocate(char **output, free(*$1));
%include "x.h"
_x.pyd: x.c x_wrap.c x.h
cl /LD /W4 /MD /Ic:\python27\include x.c x_wrap.c -link /LIBPATH:c:\python27\libs
x_wrap.c: x.i x.h
swig -python x.i
Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import x
>>> x.some_method(100,'blah',123)
'blah_123'
>>> x.some_method2(100,'blah',123)
[8, 'blah_123']
Upvotes: 2
Reputation: 8380
Not a direct answer, but what you're working on sounds sufficiently low-level that you may want to consider forgoing SWIG and using the CPython api directly. SWIG is great, but it adds another dependency and loads of generated code.
Upvotes: 1