Jim Freeze wrote:

> I can't seem to get swig to work when my function
> has a pointer argument. Here is my simple example:
> 
> swig -version
> 
> SWIG Version 1.3.9u-20030501-1037
> Copyright (c) 1995-1998
> University of Utah and the Regents of the University of California
> Copyright (c) 1998-2001
> University of Chicago
> 
> Compiled with CC
> 
> cat example.c
> int fact2(int *n) {
>   return *n *2;
> }
> 
>  cat example.i
> /* example.i */
> %module example
> %{
> /* Put header files here (optional) */
> %}
> 
> extern int fact2(int *n);
> 
> 
> ruby -r example -e 'puts Example.fact2(2)'
> -e:1:in `fact2': Expected int * (TypeError)
>         from -e:1
> 
> Everything looks correct. I see wrapper code
> in example_wrap.c that appears to be wrapping
> the int * for me, but no worky.
> 
> Any suggestions?

First, the instant gratification part of the response ;)

Modify your SWIG interface file to look like this:

     /* example.i */
     %module example

     %include typemaps.i

     extern int fact2(int *INPUT);

Re-run SWIG, re-compile, etc. and it should work as expected.

Now, for the "why" part. SWIG is no Kreskin, and it can't guess from 
this declaration:

     extern int fact2(int *n);

whether 'n' is a pointer to a single integer (as in your case), or a 
pointer to an array of integers. For that matter, it can't tell if 'n' 
is an input-only argument to fact2(), an output-only argument, or maybe 
both an input and an output to fact2(). All of this is to say, for many 
pointer argument types you will need to give SWIG some kind of hint as 
to what's going on.

For now, just take it for granted that if you include the typemaps.i 
file from the standard SWIG library:

     %include typemaps.i

that it will define a number of useful typemaps for dealing with this 
situation. You've already seen how to handle the case of a pointer 
that's really an input. But what if your function was instead using that 
argument as an output, e.g.

     void deepthought(int *answer) {
         *answer = 42;
     }

Here, 'answer' is obviously an output-only argument. So you'd use the 
OUTPUT typemap from typemaps.i:

     %include typemaps.i

     void deepthought(int *OUTPUT);

When you call this function from Ruby, you don't pass it any arguments; 
its outputs come to you as regular outputs should:

     the_answer = deepthought() # should return 42

Finally, for input-output arguments, use the INOUT typemap:

     /* example.c */
     void triple(int *n) {
         *n = (*n) * 3;
     }

     /* example.i */

     %include typemaps.i

     void triple(int *INOUT);

And to call this function from Ruby:

     tripled_value = triple(5) # should return 15

Hope this helps,

Lyle