Call c function from Java

JavaC

Java Problem Overview


How to call c function from Java. Seems c is compiler based.

I would like to call C function in Windows from Java, and GCC function fron Java too.

Any reference?

Java Solutions


Solution 1 - Java

Have a look at Java Native Interface: Getting Started.

> 2.1 Overview > > [...] write a simple Java application that calls a C function to print > "Hello World!". The process consists of the following steps: > > Create a class (HelloWorld.java) that declares the native method. Use > javac to compile the HelloWorld source file, resulting in the class > file HelloWorld.class. The javac compiler is supplied with JDK or Java > 2 SDK releases. Use javah -jni to generate a C header file > (HelloWorld.h) containing the function prototype for the native method > implementation. The javah tool is provided with JDK or Java 2 SDK > releases. Write the C implementation (HelloWorld.c) of the native > method. Compile the C implementation into a native library, creating > Hello-World.dll or libHello-World.so. Use the C compiler and linker > available on the host environment. Run the HelloWorld program using > the java runtime interpreter. Both the class file (HelloWorld.class) > and the native library (HelloWorld.dll or libHelloWorld.so) are loaded > at runtime. The remainder of this chapter explains these steps in > detail. > > 2.2 Declare the Native Method > > You begin by writing the following program in the Java programming > language. The program defines a class named HelloWorld that contains a > native method, print. > > class HelloWorld { > private native void print(); > > public static void main(String[] args) { > new HelloWorld().print(); > } > > static { > System.loadLibrary("HelloWorld"); > } > } > > The HelloWorld class definition begins with the declaration of the print native method. This is followed by a main method that > instantiates the Hello-World class and invokes the print native method > for this instance. The last part of the class definition is a static > initializer that loads the native library containing the > implementation of the print native method. > > There are two differences between the declaration of a native method > such as print and the declaration of regular methods in the Java > programming language. A native method declaration must contain the > native modifier. The native modifier indicates that this method is > implemented in another language. Also, the native method declaration > is terminated with a semicolon, the statement terminator symbol, > because there is no implementation for native methods in the class > itself. We will implement the print method in a separate C file. > > Before the native method print can be called, the native library that > implements print must be loaded. In this case, we load the native > library in the static initializer of the HelloWorld class. The Java > virtual machine automatically runs the static initializer before > invoking any methods in the HelloWorld class, thus ensuring that the > native library is loaded before the print native method is called. > > We define a main method to be able to run the HelloWorld class. > Hello-World.main calls the native method print in the same manner as > it would call a regular method. > > System.loadLibrary takes a library name, locates a native library that > corresponds to that name, and loads the native library into the > application. We will discuss the exact loading process later in the > book. For now simply remember that in order for > System.loadLibrary("HelloWorld") to succeed, we need to create a > native library called HelloWorld.dll on Win32, or libHelloWorld.so on > Solaris. > > 2.3 Compile the HelloWorld Class > > After you have defined the HelloWorld class, save the source code in a > file called HelloWorld.java. Then compile the source file using the > javac compiler that comes with the JDK or Java 2 SDK release: > > javac HelloWorld.java > >This command will generate a HelloWorld.class > file in the current directory. > > 2.4 Create the Native Method Header File > > Next we will use the javah tool to generate a JNI-style header file > that is useful when implementing the native method in C. You can run > javah on the Hello-World class as follows: > > javah -jni HelloWorld > >The name of the header file is the class name > with a ".h" appended to the end of it. The command shown above > generates a file named HelloWorld.h. We will not list the generated > header file in its entirety here. The most important part of the > header file is the function prototype for Java_HelloWorld_print, which > is the C function that implements the HelloWorld.print method: > > JNIEXPORT void JNICALL Java_HelloWorld_print (JNIEnv *, jobject); > > Ignore the JNIEXPORT and JNICALL macros for now. You may have noticed > that the C implementation of the native method accepts two arguments > even though the corresponding declaration of the native method accepts > no arguments. The first argument for every native method > implementation is a JNIEnv interface pointer. The second argument is a > reference to the HelloWorld object itself (sort of like the "this" > pointer in C++). We will discuss how to use the JNIEnv interface > pointer and the jobject arguments later in this book, but this simple > example ignores both arguments. > > 2.5 Write the Native Method Implementation > > The JNI-style header file generated by javah helps you to write C or > C++ implementations for the native method. The function that you write > must follow the -prototype specified in the generated header file. You > can implement the Hello-World.print method in a C file HelloWorld.c as > follows: > > #include > #include > #include "HelloWorld.h"
> > JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj) { > printf("Hello World!\n"); > return; > } > > The implementation of this native method is straightforward. It uses the printf function to display the string "Hello World!" and then returns. As mentioned before, both arguments, the JNIEnv pointer and the reference to the object, are ignored. > > The C program includes three header files: > > jni.h -- This header file provides information the native code needs > to call JNI functions. When writing native methods, you must always > include this file in your C or C++ source files. > stdio.h -- The code > snippet above also includes stdio.h because it uses the printf > function. > HelloWorld.h -- The header file that you generated using > javah. It includes the C/C++ prototype for the Java_HelloWorld_print > function. > 2.6 Compile the C Source and Create a Native Library > > Remember that when you created the HelloWorld class in the > HelloWorld.java file, you included a line of code that loaded a native > library into the program: > > System.loadLibrary("HelloWorld");
> > Now that all the necessary C code > is written, you need to compile Hello-World.c and build this native > library. > > Different operating systems support different ways to build native > libraries. On Solaris, the following command builds a shared library > called libHello-World.so: > > cc -G -I/java/include -I/java/include/solaris HelloWorld.c -o libHelloWorld.so > > The -G option instructs the C compiler to generate a shared library instead of a regular Solaris > executable file. Because of the limitation of page width in this book, > we break the command line into two lines. You need to type the command > in a single line, or place the command in a script file. On Win32, the > following command builds a dynamic link library (DLL) HelloWorld.dll > using the Microsoft Visual C++ compiler: > > cl -Ic:\java\include -Ic:\java\include\win32 -MD -LD HelloWorld.c -FeHelloWorld.dll > > The -MD option ensures that HelloWorld.dll is linked with the Win32 multithreaded C library. > The -LD option instructs the C compiler to generate a DLL instead of a > regular Win32 executable. Of course, on both Solaris and Win32 you > need to put in the include paths that reflect the setup on your own > machine. > > 2.7 Run the Program > > At this point, you have the two components ready to run the program. > The class file (HelloWorld.class) calls a native method, and the > native library (Hello-World.dll) implements the native method. > > Because the HelloWorld class contains its own main method, you can run > the program on Solaris or Win32 as follows: > > java HelloWorld > > You should see the following output: > > Hello World! > > It is important to set your native library path > correctly for your program to run. The native library path is a list > of directories that the Java virtual machine searches when loading > native libraries. If you do not have a native library path set up > correctly, then you see an error similar to the following: > > > java.lang.UnsatisfiedLinkError: no HelloWorld in library path > at java.lang.Runtime.loadLibrary(Runtime.java) > at java.lang.System.loadLibrary(System.java) > at HelloWorld.main(HelloWorld.java) > > Make sure that the native library resides in one of the directories in the native library path. > If you are running on a Solaris system, the LD_LIBRARY_PATH > environment variable is used to define the native library path. Make > sure that it includes the name of the directory that contains the > libHelloWorld.so file. If the libHelloWorld.so file is in the current > directory, you can issue the following two commands in the standard > shell (sh) or KornShell (ksh) to set up the LD_LIBRARY_PATH > environment variable properly: > > LD_LIBRARY_PATH=. > export LD_LIBRARY_PATH > > The equivalent command in > the C shell (csh or tcsh) is as follows: > > setenv LD_LIBRARY_PATH . > > If you are running on a Windows 95 or > Windows NT machine, make sure that HelloWorld.dll is in the current > directory, or in a directory that is listed in the PATH environment > variable. > > In Java 2 SDK 1.2 release, you can also specify the native library > path on the java command line as a system property as follows: > > java -Djava.library.path=. HelloWorld > > The "-D" command-line option > sets a Java platform system property. Setting the java.library.path > property to "." instructs the Java virtual machine to search for > native libraries in the current directory.

Solution 2 - Java

In simple terms, just make sure you load the relevant library which contains the function definition, load the library which follows the JNI specification and wraps the target function from the first library, expose native methods from your Java class and you should be good to go.

I'd recommend against raw JNI since it contains a lot of boilerplate code and you would end up cursing yourself if you start wrapping a big C library. By all means do feel free to dabble in JNI when starting out but use something like JNA when it comes to real work.

Solution 3 - Java

You options include:

Java Native Interface
see: https://en.wikipedia.org/wiki/Java_Native_Interface

quote:
> JNI enables programmers to write native methods to handle situations when an application cannot be written entirely in the Java programming language, e.g. when the standard Java class library does not support the platform-specific features or program library

Java Native Access

see: https://en.wikipedia.org/wiki/Java_Native_Access

quote:
> Java Native Access is a community-developed library that provides Java programs easy access to native shared libraries without using the Java Native Interface.

JNR-FFI

see: https://github.com/jnr/jnr-ffi

quote:
>jnr-ffi is a java library for loading native libraries without writing JNI code by hand, or using tools such as SWIG.

Solution 4 - Java

In the "exotic" category, see NestedVM, which compiles the C to Mips, and runs a Mips VM inside JVM.

http://nestedvm.ibex.org/

Solution 5 - Java

Checkout JNAerator. https://code.google.com/p/jnaerator/

You need to provide the source code and preprocessor definitions etc.

Solution 6 - Java

If you are using Windows and MinGW gcc you may need additional flag if you are getting UnsatisfiedLinkError for specific method in lib:

gcc -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -I"%JAVA_HOME%"\include -I"%JAVA_HOME%"\include\win32 BestCode.c -shared -o BestCode.dll

Solution 7 - Java

@Jonas gave a very elaborated answer, but I think its also really worth checking this website and you will get all your essential answers there :

http://www.ntu.edu.sg/home/ehchua/programming/java/javanativeinterface.html

It explains how to call a program using JNI :

  • For languages C and C++ or a mixture of both
  • JNI without any parameters, primitives, strings or Array of primitives
  • Accessing object variables, callback instances methods and much more.

Solution 8 - Java

For making 64-bit compatible dll Remove "-MD" option from statement below

cl -Ic:\java\include -Ic:\java\include\win32 -MD -LD HelloWorld.c -FeHelloWorld.dll

Solution 9 - Java

I got a solution for this problem. What you need to ensure is you're compiling the code using 64-bit c++ compiler for calling java function running on 64-bit JRE. Along with it we need to save the path of created dll file in "Path" under "Environment variable".

Solution 10 - Java

First make ensure to load your native library or .dll file in class path by setting path at property java.library.path

Then use System.loadLibrary()

Do not use .dll extension at the end.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAli IrawanView Question on Stackoverflow
Solution 1 - JavaJonasView Answer on Stackoverflow
Solution 2 - JavaSanjay T. SharmaView Answer on Stackoverflow
Solution 3 - JavaDawnkeeperView Answer on Stackoverflow
Solution 4 - JavaddyerView Answer on Stackoverflow
Solution 5 - JavaAykut KllicView Answer on Stackoverflow
Solution 6 - JavaJustinas JakavonisView Answer on Stackoverflow
Solution 7 - JavaaksView Answer on Stackoverflow
Solution 8 - JavaDila GurungView Answer on Stackoverflow
Solution 9 - JavaDila GurungView Answer on Stackoverflow
Solution 10 - Javauser3906011View Answer on Stackoverflow