How to call a C program from Java?

21/10/2012

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.
Ads by Google

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

This Core Java tutorial was posted on 21/10/2012.
Ads by Google

68 comments on “How to call a C program from Java?

  1. typo: In section 3. your #includes seems to be missing.

    • applay this….add quotes..
      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

  2. i was anxiosly wating for this topic to post

  3. Cool stuff!

    How does the process differ for Android NDK?

  4. Thanx … Because of you i am able to understand the concept of Java native interface (JNI) .

  5. Thanks a lot.. Very useful and nice one..

  6. Nice Article…

    Please explain about below line…

    JNIEXPORT void JNICALL Java_JavaToC_helloC
    (JNIEnv *, jobject);

  7. hello joe thanx for the article
    plz write some article about oops concept with example …….from the point of interview…

  8. Nice writeup – JNI is great for libraries but the overhead of the native call if a bit of a pain. If you only need to call a program (i.e. not a library) you should check out NestedVM http://nestedvm.ibex.org/. It allows you to compile C to Java byte code and run it on the JVM.

  9. Hello Sir !!! Thanks For Helping Us Regularly…

  10. Hi joe,
    Facing issue while compilation

    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

    Following error occured during compilation of Helloworld.c:
    D:\Data\Personal\java\c4mjava>tcc HelloWorld.c -I C:\Program Files\Java\jdk1.7.0_03\include -shared -o HelloWorld.dll
    HelloWorld.c:2: include file ‘jni.h’ not found

    Please give solution to this issue..

    Thanks

    • apply this….add quotes..
      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

  11. its good informative article. thanks for share with us.

  12. How to generate shared library file for the linux platform ?

  13. Its nice … Got an idea about JNI … Thnx …Keep writing :)

  14. I was waiting for this. Nice example sir. Thanks alot

  15. Hi, i am getting the following error. Could you help me resolving this error?
    C:\java\javatoc>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
    HelloWorld.C:2: include file ‘jni.h’ not found

  16. Hello Sir,

    I tried this before I did all the steps correctly but I could not be create the necessary .dll file. Should I have to install Ms visual studio for creation of .dll file. because without that i am not able to use cl command to create .dll file. Or else Please tell me the another way of creation. So that I can complete this assignment for that Please help me out Sir.

    Thankyou

  17. nice article ……………
    very helpful for java developers………

  18. Nice….

    very useful for java developers.

    Thanks.

  19. Nice one. We have used this previously.
    This one is very useful in password encryption logic.

  20. very clear understand….and easy to catch it.thanks

    • nice blog…
      very knowledgeable example…
      thnxu :)

  21. Hello Sir,
    Its a nice tutorial. Thank you so much :)
    I have one problem
    I am trying this with gcc on windows platform but I got this error:-
    Exception in thread “main” java.lang.UnsatisfiedLinkError: JavaToC.helloC()V
    at JavaToC.helloC(Native Method)
    at JavaToC.main(JavaToC.java:9)

    following the http://stackoverflow.com/questions/11420153/java-lang-unsatisfiedlinkerror-returned-when-calling-native-method answer I put underscore in header file and in my c file method name _Java_javaToC_helloC and It worked fine. Can you please explain this dependency.

  22. Good article Joe..
    Adding some more explanations will help us to understand better…

  23. I am very sorry to say joe, from last two weeks javapapers site design not al;ignd properly.all articles tab missing and footer of site not good.

    I don’t have your contact information that’s wise i am choosing this place.

    • Pyla, I am working of footer, comment and menu redesign. Will fix them soon. Thanks.

  24. Enclose the path with quotes:
    tcc HelloWorld.C -I “C:\Program Files\java\jdk1.6.0_13\include” -I “C:\Program Files\java\jdk1.6.0_13\include/win32″ -shared -o HelloWorld.dll

  25. Good stuff Joe. Helped me a lot to understand JNI.

  26. Hello,

    When I creating the .dll file at that time, it is saying tcc is not recongnised as internal or external command

  27. I downloaded tcc.zip. Inside it tcc.exe file is there. Then set path in the system evvironment variable. copied the path of tcc.exe with filename(tcc.exe) file and pasted in the path variable. Then i tried to run the command tcc ….

    it gives tcc is not recognised as internal or external command. Please help!

  28. it a innovative thinking ,so good, very helpfull

  29. Hi Joe,

    Great… I found this blog very interesting….

    If I need to keep in touch with you, what will be your email address… (if you have no reservations to share your mail id)…

    Thanks and regards
    Balaji / balajihx@gmail.com

  30. Guys who are facing “HelloWorld.C:2: include file ‘jni.h’ not found” this problem please use following command. I was getting same issue but it was solved when I used this Command:
    C:\Java2C\tcc>(path to tcc folder)

    tcc HelloWorld.c -I “C:\Program Files\Java\(whatever version u r using)jdk1.7.0_07\include” -I “C:\Program Files\Java\jdk1.7.0_07\include/win32″ -shared -o HelloWorld.dll

  31. Hi Joe,
    Is there any solution for this:
    Because I really wish to see the program running…
    C:\Java2C\tcc>java JavaToC
    Exception in thread “main” java.lang.UnsatisfiedLinkError: C:\Java2C\tcc\HelloWo
    rld.dll: Can’t load IA 32-bit .dll on a AMD 64-bit platform
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary1(Unknown Source)
    at java.lang.ClassLoader.loadLibrary0(Unknown Source)
    at java.lang.ClassLoader.loadLibrary(Unknown Source)
    at java.lang.Runtime.loadLibrary0(Unknown Source)
    at java.lang.System.loadLibrary(Unknown Source)
    at JavaToC.(JavaToC.java:6)

    • u are trying to load 32 bil .so files in 64 bit OS.

      first,compile with 64 bit then try to load in 64 bit environment

  32. I have the same issues

    C:\Dev\JNITest>c:\Dev\tcc\tcc.exe HelloWorld.C -I C:\Java\jdk1.7.0_05\include -I C:\Java\jdk1.7.0_05\include\win32 -shared -o HelloWorld.dll

    C:\Dev\JNITest>dir
    Volume in drive C is Windows
    Volume Serial Number is 2EC0-F1BC

    Directory of C:\Dev\JNITest

    02/14/2013 05:26 PM .
    02/14/2013 05:26 PM ..
    02/14/2013 05:17 PM 184 HelloWorld.c
    02/14/2013 05:26 PM 59 HelloWorld.def
    02/14/2013 05:26 PM 2,048 HelloWorld.dll
    02/14/2013 05:04 PM 450 JavaToC.class
    02/14/2013 05:06 PM 385 JavaToC.h
    02/14/2013 05:04 PM 218 JavaToC.java
    02/14/2013 05:02 PM JNIExample
    6 File(s) 3,344 bytes
    3 Dir(s) 296,163,921,920 bytes free

    C:\Dev\JNITest>java JavaToC
    Exception in thread “main” java.lang.UnsatisfiedLinkError: C:\Dev\JNITest\HelloWorld.dll: Can’t load IA 32-bit .dll on a AMD 64-bit platform
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1939)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1864)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1854)
    at java.lang.Runtime.loadLibrary0(Runtime.java:845)
    at java.lang.System.loadLibrary(System.java:1084)
    at JavaToC.(JavaToC.java:6)

  33. really excellent tutorial.i have been looking for it for a log time.THANK YOU VERY MUCH

  34. Hi i have to load .so file in cpp program and will have to call the method of same .so files.

    plz any help me out.

  35. when I compile this file this erroe show
    include file ‘jni.h’ not found

    • Set Path for jni.h and jni_md.h as

      C:\Program Files\Java\jdk1.6.0_26\include
      C:\Program Files\Java\jdk1.6.0_26\include\win32 to avoid giving parameters for -I

  36. How to use C header files in java?

  37. Explained it well. this was informative. thanks for sharing it.

  38. what is “JNIEXPORT void JNICALL Java_JavaToC_helloC(JNIEnv *env, jobject javaobj)
    “??? what is the use of it??

  39. Hello There,
    I’m using Solaris 11, and I am failing the process when compiling C code.

    -bash-4.1$ gcc -o libHelloWorld.so -shared -I/usr/java/include -I/usr/java/include/solaris HelloWorld.c -lc
    Text relocation remains referenced
    against symbol offset in file
    .rodata (section) 0×9 /var/tmp//cc.GaGrd.o
    printf 0xe /var/tmp//cc.GaGrd.o
    ld: fatal: relocations remain against allocatable but non-writable sections
    collect2: ld returned 1 exit status

    I think I have use the right code to compiling. What is wrong here???

  40. Pingback: Java JVM Run-time Data Areas

  41. Hi I am getting error, while compiling c file
    Hello.c: In function `main’:
    Hello.c:7: error: parse error before ‘{‘ token
    Hello.c:7: error: declaration for parameter “Java_JavaToC_helloC” but no such parameter

    Plz resolve it

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>