How to call a C program from Java?

Calling a C program may be useful when we prefer to use C libraries and to reuse an existing C program. When we compile a C program, the source gets converted to obj file. It is a platform dependent intermediate machine code which will be converted to exe and then executed.
Java native interface (JNI) is a framework provided by java that enables java programs to call native code and vice-versa.

Using JNI a java program has the capability to call the native C code. But we lose the core objective of java which is platform independence. So calling a C program from java should be used judiciously.
JNI provides the specification and native code should be written/ported accordingly. JDK vendor should provide the needed implementation for the JNI.

Steps to call a C program from Java

1. Write the Java Program and Compile
2. Generate header file from java class
3. Write the C Program
4. Generate Shared Library File
5. Run Java Program

1. Write the Java Program

public class JavaToC {
 
    public native void helloC();
 
    static {
        System.loadLibrary("HelloWorld");
    }
 
    public static void main(String[] args) {
        new JavaToC().helloC();
    }
}
Note two things in this program,
  • Use of native keyword. This is a method declaration and it informs the java compiler that the implementation for this method is a native one. This method helloC() is present in C source file and that is what we are going to call.
  • Loading the library HelloWorld using static keyword. This library file will be compiled out of the C source in the coming steps.

2. Generate header file from java class

  • JDK provides a tool named javah which can be used to generate the header file.
  • We will use the generated header file as include in C source.
  • Remember to compile the java program before using javah
javah JavaToC
Following is the header file generated,
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class JavaToC */
 
#ifndef _Included_JavaToC
#define _Included_JavaToC
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     JavaToC
* Method:    helloC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_JavaToC_helloC
(JNIEnv *, jobject);
 
#ifdef __cplusplus
}
#endif
#endif

3. Write the C Program

#include <stdio.h>
#include <jni.h>
#include "JavaToC.h"
JNIEXPORT void JNICALL Java_JavaToC_helloC(JNIEnv *env, jobject javaobj)
{
  printf("Hello World: From C");
  return;
}
  • stdio.h is the standard C header file include.
  • jni.h is the header file that provides the java to C mapping and it is available in JDK.
  • JavaToC.h is the header file generated from the java source file.

4. Generate Shared Library File

  • Now compile the above C source file. We need a C compiler and I have chosen Tiny C.
  • Tiny C can be downloaded from http://mirror.veriportal.com/savannah//tinycc/tcc-0.9.25-win32-bin.zip
    Download and unzip the file and set OS path to tcc.exe
  • tcc HelloWorld.C -I C:/Progra~1/Java/jdk1.7.0_07/include -I C:/Progra~1/Java/jdk1.7.0_07/include/win32 -shared -o HelloWorld.dll
  • Above is the command to generate the shared library file dll which is loaded in the java program. Two directories are included in the compile command, those are to include the jni.h and jni_md.h

5. Run Java Program

We are all set, now run the java program to get the following output,
Hello World: From C

0 comments:

Post a Comment