Java wrapper for .c code

I have the following c code:

test.c

#include <stdio.h> #include <math.h> int add (int a, int b) { a=4; b=4; return a+b; } int add_pointer (int *a, int *b) { printf("values of a,b: %d,%d \n",*a,*b); return ((*a)+(*b)); } char* print_hello() { return "hello_world"; } 

test.h

 #ifndef TEST_H_ #define TEST_H_ int add(int a, int b); int add_pointer (int *a, int *b); char *print_hello(); #endif 

main.c

 #include "test.h" #include <stdio.h> #include <math.h> int main() { int a,b,c,d; char* rez; a=5; b=2; //int *r=&a; c= add(a,b); d=add_pointer(&a,&b); rez=print_hello(); printf("sum is: %d and : %s %d \n",c,rez,d); return 0; } 

test_app.i

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

I want to create a java shell for this .c code. I would like to use this shell later in an android demo.

I have done the following:

 $: swig -java test_app.i 

FURTHER:

 test_app_wrapper.c test_app.java test_appJNI.java SWIGTYPE_p_int.java $: gcc -fpic -c test.c test_app_wrap.c -I /usr/lib/jvm/java-7-openjdk-amd64/include -I /usr/lib/jvm/java-7-openjdk-amd64/include/linux $: gcc -shared test.o test_app_wrap.o -o libtest_app_wrap.so 

UPDATE:

HelloWorld.java

  public class HelloWorld { native String print_hello(); /* (1) */ static { System.loadLibrary("test_app_wrap"); /* (2) */ } static public void main(String argv[]) { HelloWorld helloWorld = new HelloWorld(); helloWorld.print_hello(); /* (3) */ } } 

At startup:

 $: javac HelloWorld.java $ java HelloWorld 

I have:

 Exception in thread "main" java.lang.UnsatisfiedLinkError: no test_app_wrap in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1856) at java.lang.Runtime.loadLibrary0(Runtime.java:845) at java.lang.System.loadLibrary(System.java:1084) at HelloWorld.<clinit>(HelloWorld.java:4) 

What am I doing wrong?

+4
source share
2 answers

When you execute swig -java test_app.i , it creates the Java glue classes that you must include in your Java project. The main interface created is called test_app.java and looks like this:

 public class test_app { public static int add(int a, int b) { return test_appJNI.add(a, b); } public static int add_pointer(SWIGTYPE_p_int a, SWIGTYPE_p_int b) { return test_appJNI.add_pointer(SWIGTYPE_p_int.getCPtr(a), SWIGTYPE_p_int.getCPtr(b)); } public static String print_hello() { return test_appJNI.print_hello(); } } 

As you can see, it delegates all calls to test_appJNI , which is also automatically generated, and acts like glue on its own code (using native methods):

 public class test_appJNI { public final static native int add(int jarg1, int jarg2); public final static native int add_pointer(long jarg1, long jarg2); public final static native String print_hello(); } 

So you should:

  • include how generated .java files in the project
  • make sure you download the .so library with System.loadLibrary("test_app_wrap"); “You already did it.”
  • just call test_app.print_hello()

We also recommend that you read section 21 of SWIG and Java from the SWIG manual. A preview and overview of the main sections of the C / C ++ wrapper fully explain all the basics.

A received error indicates that the JVM cannot load the .so library. My first question would be if it were compiled and properly linked. If you are sure that you have libtest_app_wrap.so , this may not be in the way where the JVM is looking for it (check this out - http://www.chilkatsoft.com/p/p_499.asp ). For instance. for me it was necessary to add -Djava.library.path=. to the Java command line:

 java -Djava.library.path=. HelloWorld 

For reference - I modified your HelloWorld.java file:

 public class HelloWorld { static { System.loadLibrary("test_app_wrap"); } static public void main(String argv[]) { test_app.print_hello(); } } 

Hope that helps :)

+1
source

You don't seem to understand how jni works, check out this tutorial:

Calling C code from Java using JNI

Your test_app_wrap does not exist to use JNI, you need to assign a specific name to your C functions and then create a Java class with your own methods to call them i.e.

 native String print_hello(); 

and in the Java class, load your own library.

Then you create a Java YourClass object and call the print_hello() native method

+2
source

All Articles