Martin DeMello wrote:
I have some C code with two exported functions, which I'm trying to wrap
via swig. THe signatures are:
int dawg_init(char *filename, NODE ** dawgp, INDEX * nedgesp);
void processRack(NODE *dawg, char *rack);
where NODE and INDEX are C typedefs for long.
In the C code, I say
NODE *dawg;
INDEX nedges;
char *rack;
dawg_init(dictFileName, &dawg, &nedges);
processRack(dawg, rack);
How do I get swig to have my ruby code look like
dawg = dawg_init(dictFilename)
processRack(dawg, rack)
I have to head out to run some errands, but here are some quick hints. First of all, if these two functions are all you're trying to wrap, SWIG is probably overkill. SWIG is best for large libraries where you're willing to settle for the un-Rubyness of the wrapped API in return for having the wrappers automatically generated. For two functions, I'd probably hand-code the wrappers as described in the Pickaxe--especially if you want to change the method signatures. Or use Ruby Inline, about which I know little except that it exists and looks interesting.
The SWIG technique for handling function arguments that are for return values only is the 'argout' typemap. Here's an example from one of my SWIG interface files:
-------- snip ---------
/*
* Input typemap for output structs
*/
%typemap(ruby, in, numinputs=0) struct any *OUTPUT {
$1 = ALLOC($*1_type);
}
/*
* Argout typemap for output structs
*/
%typemap(argout, fragment="output_helper") struct any *OUTPUT {
$result = output_helper($result,
SWIG_NewPointerObj($1, $1_descriptor, 1));
}
/*
* Apply above rules to output structs not requiring special handling
*/
%apply(struct any *OUTPUT) {
CAPI_CATC_T *catcP,
CAPI_USERINFO_T *userinfoP,
CAPI_DIAG_SYMBOL_T *symbP,
CAPI_DIAG_T *OUTPUT,
CAPI_FRAME_INFO_T *OUTPUT,
CAPI_FRAME_DEFN_T *fdefnP,
CAPI_FRAME_INFO_T *OUTPUT,
CAPI_FRAME_TYPE_T *ftypeP,
CAPI_ITEMSTATE_E *stateP,
CAPI_ITEM_T *OUTPUT,
CAPI_LINKED_ITEM_T *linkP,
CAPI_LIST_T *OUTPUT,
CAPI_NOTE_T *OUTPUT,
CAPI_PROJECT_T *OUTPUT,
CAPI_QUERY_T *OUTPUT
}
-------- snip ---------
The 'in' typemap generates code to allocate the structure, 'numinputs=0' tells the wrapper not to expect a corresponding argument in the Ruby call. The 'argout' typemap wraps the struct (after return from the C function) in the proper Ruby class and adds it to the array of returned values. Omitting the int return value from dawg_init will require an 'out' typemap, I think. I've never used those.
The 'in' typemap above is Ruby-specific, because it calls Ruby's wrapper around malloc(). SWIG doesn't have, or I couldn't find, a language-independent macro for that. The 'argout' typemap is language-independent.
But really, I'd just do it by hand. The Ruby C API is pretty sweet.
Back later.
Steve