1

I have a simple C library that I use from Java. The bridge is fully working. However, one of the methods requires an array, resulting in unwanted memory allocation/deallocation.

SWIG code:

typedef struct {} Foo;
%apply short[] {const int16 *FOODATA};

%extend Foo {
    Foo(size_t bufferSize, int *errcode) {

        /* WHAT TO DO WITH BUFFER SIZE?? */

        Foo *foo = foo_create();
        *errcode = foo ? 0 : -1;
        return foo;
    }

    ~Foo() {
        foo_free($self);
    }

    void bar(const int16 *FOODATA, size_t FOOSIZE, int *errcode) {
        *errcode = foo_bar($self, FOODATA, FOOSIZE);
    }
}

Java code:

final int bufferSize = 32768;
final short[] bar = new short[bufferSize];
Foo foo = new Foo(bufferSize);
for (int i = 0; i < 1000; i++) {
    // Fill bar with at most 32768 beers...
    // ...

    foo.bar(bar, bar.length);
}

This works but each call to bar() implies an allocation using malloc() and a subsequent deallocation using free() - in SWIG generated code. Obviously, this is a waste of resources.

How can I avoid the temporary memory allocation/deallocation for my array sent to foo_bar()?

Obviously, the buffer size is known beforehand so it should be possible to pre-allocate a buffer and tell SWIG to use that.

l33t
  • 18,692
  • 16
  • 103
  • 180
  • Somebody somewhere has to allocate the memory for it. Are you hoping to have the `Foo` constructor do the allocation for you and make it usable from Java? – Flexo Nov 19 '18 at 19:50
  • I solved it using `java.nio.ByteBuffer`. – l33t Nov 19 '18 at 19:55
  • That's a pretty good solution by the sounds of things - care to write it up as an answer for others? – Flexo Nov 19 '18 at 19:55
  • I ended up using `ByteBuffer` as described in [this answer](https://stackoverflow.com/a/32474455/419761). – l33t Nov 19 '18 at 20:08

0 Answers0