Skip to content

Instantly share code, notes, and snippets.

@mbogochow
Last active December 6, 2017 15:35
Show Gist options
  • Save mbogochow/ff8568d2392537c4b766b3dcaf7dd836 to your computer and use it in GitHub Desktop.
Save mbogochow/ff8568d2392537c4b766b3dcaf7dd836 to your computer and use it in GitHub Desktop.
SWIG Proxy Class Array Parameter
#include "demo.h"
#include <iostream>
using namespace std;
void myFunction(struct MyStruct arg[], int amount)
{
for (int i = 0; i < amount; i++) {
cerr << " el[" << i << "] a=" << arg[i].a << ", b=" << arg[i].b << std::endl;
}
}
#ifndef DEMO_H
#define DEMO_H
struct MyStruct {
int a;
int b;
};
void myFunction(struct MyStruct arg[], int amount);
#endif /* DEMO_H */
%module Demo
%pragma(java) jniclasscode=%{
static {
try {
System.loadLibrary("demo");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load: " + e.getMessage());
throw e;
}
}
private DemoJNI()
{
throw new IllegalStateException("Instances of class " + getClass().getSimpleName() + " should not be instantiated");
}
%}
%pragma(java) modulecode=%{
public static void main(String[] args) {
MyStruct[] ms = new MyStruct[4];
System.err.println("Java level:");
for (int i = 0; i < 4; i++) {
ms[i] = new MyStruct();
ms[i].setA(i);
ms[i].setB(i + 1);
System.err.println(" " + ms[i].getA() + ", " + ms[i].getB());
}
myFunction(ms, 4);
}
%}
%{
#include "demo.h"
%}
// In order to allow classes generated from this module to be available to other
// modules, we need to set the constructor and getCPtr method as public.
// http://www.swig.org/Doc2.0/Java.html
%include <java.swg>
SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)
SWIG_JAVABODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
%include <carrays.i>
%array_class(struct MyStruct, MyStructArray);
%typemap(jni) MyStruct arg[] "jobject"
%typemap(jstype) MyStruct arg[] "MyStruct[]"
%typemap(jtype) MyStruct arg[] "MyStructArray"
%typemap(javain, pre=" if ($javainput.length == 0 || $javainput.length < amount)
throw new IllegalArgumentException(\"Must provide big enough array\");
MyStructArray arr = new MyStructArray(amount);
System.err.println(\"javain level:\");
for (int i = 0; i < amount; i++) {
arr.setitem(i, $javainput[i]);
System.err.println(\" \" + arr.getitem(i).getA() + \", \" + arr.getitem(i).getB());
}
System.err.println(\"C++ level:\");") MyStruct arg[] "arr"
%typemap(in) MyStruct arg[] {
jclass objectClass = jenv->GetObjectClass(jarg1);
jmethodID getCPtrMethod = jenv->GetStaticMethodID(objectClass, "getCPtr", "(LMyStructArray;)J");
if (getCPtrMethod == NULL)
return $null;
jlong cptr = jenv->CallStaticLongMethod(objectClass, getCPtrMethod, jarg1);
arg1 = (MyStruct *) cptr;
}
%include "demo.h"
CC=g++
LD=$(CC)
JC=javac
DEPS=demo.h
OBJ=demo.o demo_wrap.o
LIB_OUT=libdemo.so
JAVA_HOME?=$(shell readlink -f /usr/bin/javac | sed "s:bin/javac::")
IFLAGS=-I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux
JAVA_CLASSES=Demo DemoJNI MyStruct MyStructArray
JAVA_SRC=$(patsubst %,%.java,$(JAVA_CLASSES))
JAVA_OUT=$(patsubst %,%.class,$(JAVA_CLASSES))
SWIG_GENERATED=$(JAVA_SRC) demo_wrap.cxx
all: $(LIB_OUT) java
demo.o: demo.cpp
demo_wrap.o: demo_wrap.cxx
$(OBJ):
$(CC) -c -o $@ $^ $(IFLAGS) -fPIC
$(LIB_OUT): $(OBJ)
$(LD) -o $(LIB_OUT) $(OBJ) -shared
java: $(JAVA_OUT)
$(JAVA_OUT): %.class : %.java
$(JC) $^
swig: $(SWIG_GENERATED)
$(SWIG_GENERATED): demo.i $(DEPS)
swig -c++ -java demo.i
clean:
rm -rf *.so *.o *.java *wrap.cxx *.class
.PHONY: all clean swig java
#!/bin/bash
java -Djava.library.path=. Demo
@mbogochow
Copy link
Author

This answers my own stack overflow question

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment