calling a swig generated function

Discussion in 'Ruby' started by Michael Hale, Aug 19, 2004.

  1. Michael Hale

    Michael Hale Guest

    I have a library that I wrapped with SWIG. One of the SWIG generated
    functions looks like this:

    static VALUE
    _wrap_NSCalculateGap(int argc, VALUE *argv, VALUE self) {
    int arg1 ;
    int arg2 ;
    unsigned long arg3 ;
    double arg4 ;
    unsigned long *arg5 = (unsigned long *) 0 ;
    int arg6 ;
    int arg7 ;
    int arg8 ;
    int result;
    VALUE vresult = Qnil;

    if ((argc < 8) || (argc > 8))
    rb_raise(rb_eArgError, "wrong # of arguments(%d for 8)",argc);
    arg1 = NUM2INT(argv[0]);
    arg2 = NUM2INT(argv[1]);
    arg3 = NUM2ULONG(argv[2]);
    arg4 = (double) NUM2DBL(argv[3]);
    SWIG_ConvertPtr(argv[4], (void **) &arg5, SWIGTYPE_p_unsigned_long,
    1);
    arg6 = NUM2INT(argv[5]);
    arg7 = NUM2INT(argv[6]);
    arg8 = NUM2INT(argv[7]);
    result =
    (int)NSCalculateGap(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8);

    vresult = INT2NUM(result);
    return vresult;
    }

    How should I call this function from ruby? I am having problems with
    arg5. Here is my current attempt:

    pulGap = 0
    Smartlib::NSCalculateGap(iMode, iSpeed, ulPacketLength, dValue,
    pulGap, hub, slot, port)

    However this gives me the following error:

    TypeError: wrong argument type Fixnum (expected Data)

    Also here is an example from the library documetation:

    int iMode = PERCENT_LOAD_TO_GAP_BITS
    int iSpeed = SPEED_10GHZ
    unsigned long ulPacketLength = 100
    double dValue = 95.5
    unsigned long ulGap = 0;
    NSCalculateGap(iMode,iSpeed,dValue,&ulGap,iHub,iSlot,iPort);

    Thanks, Michael

    "OS X: because it was easier to make UNIX user-friendly than to fix
    Windows"
    Michael Hale, Aug 19, 2004
    #1
    1. Advertising

  2. Michael Hale

    Lyle Johnson Guest

    On Thu, 19 Aug 2004 09:58:32 +0900, Michael Hale
    <> wrote:

    > I have a library that I wrapped with SWIG. One of the SWIG generated
    > functions looks like this:


    <snip>

    I'm guessing that the fifth argument is declared as a pointer to an
    unsigned long, correct? The problem is that SWIG doesn't know which
    one of the many interpretations of that to use. In this case, it
    appears that the NSCalculateGap() function uses that unsigned long
    pointer argument to return a value (i.e. for output), but as far as
    SWIG knows you could be passing in a single unsigned long value, or
    even an array of unsigned longs, as input.

    > How should I call this function from ruby?


    You're going to need to use a typemap of some kind to let SWIG know
    that, in this case, that unsigned long pointer argument is actually an
    output value. Depending on how you've written your SWIG interface
    file, you'll want to do something like this:

    // Include declarations for output typemaps from the SWIG library
    %include typemaps.i

    // Apply SWIG's OUTPUT typemap for unsigned long values to the
    "ulGap" argument
    %apply unsigned long *OUTPUT { unsigned long ulGap; }

    // Here's what I would guess the actual function declaration looks like...
    void NSCalculateGap(int iMode, int iSpeed, unsigned long
    ulPacketLength, double dValue, unsigned long *ulGap, int iHub, int
    iSlot, int iPort);

    Now, when you call this function from Ruby you will only pass in the
    seven input arguments, and catch the output value as the method
    result, e.g.

    ulGap = Smartlib::NSCalculateGap(iMode, iSpeed, ulPacketLength,
    dValue, hub, slot, port)

    For more information, see the "Argument Handling" chapter of the SWIG manual:

    http://www.swig.org/Doc1.3/Arguments.html

    Hope this helps,

    Lyle
    Lyle Johnson, Aug 19, 2004
    #2
    1. Advertising

  3. Michael Hale

    Michael Hale Guest

    Thank you for the suggestion. I was able to get my code to work with
    the following in my smartlib.i file:

    %apply unsigned long *OUTPUT { unsigned long *pulGap };

    Now I call the function like this:

    NSCalculateGap(iMode, iSpeed, ulPacketLength, dValue, hub, slot, port)

    And get back an array with the first element being the original return
    value and the second being the value of the pulGap pointer. Like this:

    [0,1273]

    BTW here is the method definition from my header file:

    int DLL_EXPORT NSCalculateGap(int iMode, int iSpeed,
    unsigned long ulPacketLength,
    double dValue,
    unsigned long *pulGap,
    int iHub, int iSlot, int iPort);


    On Aug 19, 2004, at 9:09 AM, Lyle Johnson wrote:

    > On Thu, 19 Aug 2004 09:58:32 +0900, Michael Hale
    > <> wrote:
    >
    >> I have a library that I wrapped with SWIG. One of the SWIG generated
    >> functions looks like this:

    >
    > <snip>
    >
    > I'm guessing that the fifth argument is declared as a pointer to an
    > unsigned long, correct? The problem is that SWIG doesn't know which
    > one of the many interpretations of that to use. In this case, it
    > appears that the NSCalculateGap() function uses that unsigned long
    > pointer argument to return a value (i.e. for output), but as far as
    > SWIG knows you could be passing in a single unsigned long value, or
    > even an array of unsigned longs, as input.
    >
    >> How should I call this function from ruby?

    >
    > You're going to need to use a typemap of some kind to let SWIG know
    > that, in this case, that unsigned long pointer argument is actually an
    > output value. Depending on how you've written your SWIG interface
    > file, you'll want to do something like this:
    >
    > // Include declarations for output typemaps from the SWIG library
    > %include typemaps.i
    >
    > // Apply SWIG's OUTPUT typemap for unsigned long values to the
    > "ulGap" argument
    > %apply unsigned long *OUTPUT { unsigned long ulGap; }
    >
    > // Here's what I would guess the actual function declaration looks
    > like...
    > void NSCalculateGap(int iMode, int iSpeed, unsigned long
    > ulPacketLength, double dValue, unsigned long *ulGap, int iHub, int
    > iSlot, int iPort);
    >
    > Now, when you call this function from Ruby you will only pass in the
    > seven input arguments, and catch the output value as the method
    > result, e.g.
    >
    > ulGap = Smartlib::NSCalculateGap(iMode, iSpeed, ulPacketLength,
    > dValue, hub, slot, port)
    >
    > For more information, see the "Argument Handling" chapter of the SWIG
    > manual:
    >
    > http://www.swig.org/Doc1.3/Arguments.html
    >
    > Hope this helps,
    >
    > Lyle
    >
    >
    >

    "OS X: because it was easier to make UNIX user-friendly than to fix
    Windows"
    Michael Hale, Aug 20, 2004
    #3
  4. Michael Hale

    Lyle Johnson Guest

    On Sat, 21 Aug 2004 06:47:08 +0900, Michael Hale
    <> wrote:

    > Thank you for the suggestion. I was able to get my code to work with
    > the following in my smartlib.i file:
    >
    > %apply unsigned long *OUTPUT { unsigned long *pulGap };
    >
    > Now I call the function like this:
    >
    > NSCalculateGap(iMode, iSpeed, ulPacketLength, dValue, hub, slot, port)
    >
    > And get back an array with the first element being the original return
    > value and the second being the value of the pulGap pointer. Like this:
    >
    > [0,1273]


    OK, good!

    > BTW here is the method definition from my header file:
    >
    > int DLL_EXPORT NSCalculateGap(int iMode, int iSpeed,
    > unsigned long ulPacketLength,
    > double dValue,
    > unsigned long *pulGap,
    > int iHub, int iSlot, int iPort);


    Yes, I couldn't tell from your previous example (in the original post)
    what kind of return value, if any, NSCalculateGap() was declared to
    have -- so I guess a void return type. If you only want the wrapped
    version of NSCalculateGap() to return a single value (the gap) and not
    that two-element array, you might be able to do something like this:

    %extend {
    unsigned long NSCalculateGap(int iMode, int iSpeed, unsigned
    long ulPacketLength, double dValue, int iHub, int iSlot, int iPort) {
    int iResult;
    unsigned long ulGap;
    iResult = NSCalculateGap(iMode, iSpeed, ulPacketLength,
    dValue, &ulGap, iHub, iSlot, iPort);
    return ulGap;
    }
    }

    In other words, we're introducing a helper function in the middle that
    calls the "real" NSCalculateGap() function and ignores its integer
    return value. If that integer return value shouldn't be ignored --
    say, because it is an error code or something -- you might want to
    check it first and raise an exception, or whatever makes sense for
    your application.

    Hope this helps,

    Lyle
    Lyle Johnson, Aug 21, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. julia

    SWIG generated... TypeError

    julia, Sep 27, 2004, in forum: Python
    Replies:
    0
    Views:
    429
    julia
    Sep 27, 2004
  2. Bo Peng
    Replies:
    0
    Views:
    299
    Bo Peng
    Feb 2, 2005
  3. Replies:
    0
    Views:
    333
  4. Bryan
    Replies:
    0
    Views:
    267
    Bryan
    Jan 10, 2010
  5. MRAB
    Replies:
    0
    Views:
    403
Loading...

Share This Page