[Java – C] C function calls in Java – Call C function in Java

Have you ever wanted to write a Java program library but not like some languages (such as C) to perform? That is one reason for you to read this article, or some other reason do you want to use functions from C to Java programs you can run faster!

To do this, you need to use JNI library (Java Native Interface), it can call C functions from Java and vice versa. Basically, we will write the function in C, translated into the library and call the functions from Java libraries through JNI. We'll turn it gradually learn through examples of functions called factorial. Note I wrote the following files to the same folder all the Desktop.

In the process of implementation, his work on Ubuntu, on Windows or Linux distro that can vary somewhat. This article I wrote after consultation 2 Posts Calling C functions from Java and Call c function from Java, However, the implementation process has encountered some errors and their solutions are also included.

Table of Contents
Step 1: Create and compile the file into java class files
Step 2: Create a header file with javah
Step 3: Compile C library to share
Step 4: Run java
Fix some bugs

Step 1: Create and compile the file into java class files


At this stage we need to load the library and function declaration is written from C.

class CallCFunction {
	
	// report funcion write in C.
	private native long factorial(int n);
	public static void main(String[] args) {
		CallCFunction ccf = new CallCFunction();
		int n = 5;
		System.out.println(n + "! = " + ccf.factorial(5));
	}
	
	// load library factorial to use.
	static {
		System.loadLibrary("factorial");
	}
}

After creating the file in order to translate it:

javac CallCFunction.java

Step 2: Create a header file with javah

Factorial function C program written in java file that has been declared, So we need to create a header file to be used.

javah -jni CallCFunction

After executing the above command, file CallCFunction.h will be created. You pay attention to the line 15,16, Here is the function we'll write in C program.

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class CallCFunction */

#ifndef _Included_CallCFunction
#define _Included_CallCFunction
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     CallCFunction
 * Method:    factorial
 * Signature: (I)J
 */
JNIEXPORT jlong JNICALL Java_CallCFunction_factorial
  (JNIEnv *, jobject, jint);

#ifdef __cplusplus
}
#endif
#endif

Step 3: Compile C library to share


Create file factorial.c Containing calculated factorial. You copy 2 current 15, 16 CallCFunction.h file and fill in more of us are turning to the program below.

#include <jni.h>  
#include <stdio.h>  
#include "CallCFunction.h"   
JNIEXPORT jlong JNICALL Java_CallCFunction_factorial (JNIEnv *env, jobject obj, jint n)
{
	printf("funcion 'factorial' create in C programn");
	int i;
	long result = 1;
	for (i = 2; i <= n; i++)
	{
		result *= i;
	}

	return result;
}

In that, second line 4 is a function that calculates the factorial, jlong only the return value as a long, 2 parameters JNIEnv * env and jobject obj is the default and you do not need attention (its also not aware of it), parameter 3 was jint n refers variables int n corresponding in function factorial(int n) in file CallCFunction.java.

Now we will create a library and share it to the folder containing java (folder containing your java may differ offline). In CallCFunction.java we load file library factorial command System.loadLibrary(“factorial”);, library so we have more strings lib Previous ie libfactorial.so

gcc -shared -I/usr/lib/jvm/jdk1.8.0_05/include/ factorial.c -o libfactorial.so

Step 4: Run java


Now we are benefiting by running the program only.

java -Djava.library.path=. CallCFunction

The -Djava.library.path=. is tell the program can find the library you just created in the current directory (file folder libfactorial.so). Also you can set the environment variable to the directory with the command export LD_LIBRARY_PATH=. (with a dot at the end), then you can run right by command java CallCFunction

call c in java

Fix some bugs


In the process of implementation, I have met some errors, if you are like me try to follow the following remedies, If any other error you can share on this same exchange.

1. Unable to translate java command Band
If you can not translate java javac command despite installing jdk then perhaps you have not set the environment variable for it. You find out the java file, javac, javah located in any directory and proceed environment variable to the directory. Suppose JDK in “/usr/lib/jvm/jdk1.8.0_05/”

export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_05/
export PATH=$JAVA_HOME/bin:$PATH

2. Unable to find library jni.h
If the service that the error did not find this library, it would not set environment variables to use. and you should do this. For example, his:

export LD_LIBRARY_PATH=/usr/lib/jvm/jdk1.8.0_05/include/

3. Error creating file header
In the process of creating a header file (CallCFunction.h), you may encounter the following error:

Exception in thread "main" java.lang.IllegalArgumentException: Not a valid class name: HelloWorld
	at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:129)
	at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:107)
	at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:64)
	at com.sun.tools.javah.JavahTask.run(JavahTask.java:503)
	at com.sun.tools.javah.JavahTask.run(JavahTask.java:329)
	at com.sun.tools.javah.Main.main(Main.java:46)

That's when you execute the command in a different folder does not contain the * .class files generated translation * .java. In other words, can not find the file * .class. You need to put classpath to the folder containing the class file. Assuming it is in Desktop.

javah -jni -classpath /home/nguyenvanquan7826/Desktop/ HelloWorld

4. Unable to find library jni_md.h
You find out where this library computer. His, It is located at /usr/lib/jvm/jdk1.8.0_05/include/linux, Now just copy it to /usr/lib/jvm/jdk1.8.0_05/include/ (forder file contains jni.h).