How to create SWIG typemap for function that takes and returns 2 tables

114 Views Asked by At

This is my SWIG typemap:

%apply (float *INOUT, int) {(float *io1, int n1)};
%apply (float *INOUT, int) {(float *io2, int n2)};

And This is my function:

 void process(float *io1, int n1, float *io2, int n2)
    {
        for (int i = 0; i < n1; ++i)
        {
            io1[i] = io1[i] * 0.1;
            io2[i] = io2[i] * 0.1;
        }
    }

I expect the process function to take 2 tables and return 2 tables.

In Lua, the process function seems to return 2 tables but it only returns the same 2 tables which is passed from the first argument.

For example In Lua, when I run the following:

local a, b = {3}, {4}
local c, d = process(a, b)
print(c[1], d[1])

The result I get:

0.3 0.3

But I expect:

0.3 0.4

How should I change the SWIG typemap to make it work as expected?

1

There are 1 best solutions below

0
Henri Menke On BEST ANSWER

I cannot reproduce your problem with the following minimal example.

test.i

%module example
%{
#include "test.h"
%}

%include <typemaps.i>

%apply (float *INOUT, int) {(float *io1, int n1)};
%apply (float *INOUT, int) {(float *io2, int n2)};

%include "test.h"

test.h

#pragma once

void process(float *io1, int n1, float *io2, int n2);

test.c

#include "test.h"

void process(float *io1, int n1, float *io2, int n2) {
    for (int i = 0; i < n1; ++i) {
        io1[i] = io1[i] * 0.1;
        io2[i] = io2[i] * 0.1;
    }
}

test.lua

local example = require("example")
local a, b = {3}, {4}
local c, d = example.process(a, b)
print(c[1], d[1])

Then I compile and run using

$ swig -lua test.i
$ cc -fPIC -shared -I /usr/include/lua5.3/ test_wrap.c test.c -o example.so                                             
$ lua5.3 test.lua
0.30000001192093    0.40000000596046

The garbage values after the 7th decimal digit stem from the promotion of float to lua_Number which is double by default.

Disregarding this, I see the expected 0.3 0.4. That means the error must be in some code that you have not shown. Make sure to %apply the typemaps before parsing the prototype of process, i.e. in the example above note how %apply comes before %include "test.h".