Call c function in Java program--print "HelloWorld" __ Block chain

Source: Internet
Author: User
Tags class definition function prototype modifier

Source Address: http://java.sun.com/docs/books/jni/html/start.html#26346

This article is to separate the second chapter in the book, the red part of the translator note.

1. Overview

The printing process is to write a simple Java program with JDK or Java 2 SDK, and the program will call a C function to print "HelloWorld". This process will include the following steps: Creating a Java Class (Helloworld.java), and define a native method. Use Javac to compile this HelloWorld source file and generate Helloworld.class. Use Javah–jni to generate the header file (HelloWorld.h) of C, which contains the implementation prototype of the native method. Javah is a tool provided by the JDK or the Java 2 SDK. Write C code (HELLOWORLD.C) To implement this native method. Compile the implementation of this c into the Java Native Library, creating HelloWorld.dll or libhello-world.so. Run the HelloWorld program using the Java Runtime interpreter. Either the class file (Helloworld.class) or the native library (HelloWorld.dll or libhelloworld.so) is loaded at run time.

The remaining sections describe these steps in detail:

2.Native Method Declaration

Write the following program in the Java language. The program defines the class name as HelloWorld, containing a native method, print.

Class HelloWorld {
     Private native void print ();
     public static void Main (string[] args) {
         New HelloWorld (). print ();
     }
     static {
         System.loadlibrary ("HelloWorld");
     }
}

The class is not in any package

The HelloWorld class definition starts with a local method of print. The second is the main method, which instantiates a helloworld and invokes the local method of the print of this instance. The last part of the class definition is a static code block, It loads the native library that contains the print local method implementation.

There are two differences between the definition of a native method (for example, print) and the definition of a regular Java language method. A local method declaration must contain a native modifier, and the native modifier indicates that the method is implemented in another language. In addition, the definition of a local method ends with a semicolon, Because there is no local method implemented in the class itself, we will implement this print method in a separate C file.

Before calling local method print, the native library must load the implementation of the print. In this case, we load the native library in the static code block of the HelloWorld class, and the Java Virtual Opportunity automatically runs the static code block, And before calling a method of any HelloWorld class to ensure that the native library is loaded before the print local method call.

We define a main method that can run Helloworld,helloworld.main to invoke the local method to print, just as it would call a regular method.

System.loadlibrary needs a library name, then navigates to the native library that matches the name, and loads it into the application's native library. We'll discuss the loading process later in this book. Now simply Remember, For System.loadlibrary ("HelloWorld") to succeed, we need to create a native library to invoke HelloWorld.dll on the Win32 or on Solaris.

3. Compile HelloWorld

After you define the HelloWorld class, save the source code as a file Helloworld.java, and then compile the source with the Javac compiler:

Javac Helloworld.java

This command will generate a Helloworld.class file in the current directory.

4. Create a header file for the native method

Next, we'll use the Javah tool to generate a JNI-style (jni-style) header file. This is useful when implementing a local method on C. You can run Javah on the Helloworld.class, just like the following:

Javah–jni HelloWorld

The name of the generated header file is appended with a ". h" after the class name. The command shown above will generate a file named HelloWorld.h. We will not be here to list the generated header files. This header file is the most important part of the Java_helloworld_print function prototype, This is the Helloworld.print method of the C function implementation:

Jniexport void Jnicall

Java_helloworld_print (jnienv *, jobject);

Jniexport and Jnicall macros are now ignored. You may have noticed that the implementation of local method C received two parameters, whereas the corresponding native method declaration does not receive any arguments. For each local method implementation, the first parameter is the JNIEnv interface pointer (jnienv interface pointer), the second argument is a pointer to the HelloWorld object itself (a bit like C + + "This" pointers) Reference. We'll discuss how to use the JNIEnv interface pointers and Jobject later in this book. But now this simple example ignores these two parameters.

5. Write the implementation of the local method

The JNI-style header file generated with Javah can help you to complete the local method implementation of C + +. The function you write must follow the prototype of the generated header file. You can implement the Helloworld.print method in the C file helloworld.c, just like the following:

#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"
Java_helloworld_print (jnienv *env, Jobject obj)
{
    printf ("Hello world!/n");
    Return
}

The implementation of this local method is simple, it uses the printf function to display the string "helloworld!", and then returns. As mentioned earlier, two arguments, jnienv pointers, and references to objects are ignored.

This C program contains three header files: jni.h--This header file provides information that the local code needs to invoke the JNI function. When writing a local method, you must always include this file in your C or C + + source file. stdio.h--The above code snippet also contains stdio.h because it uses the printf function. helloworld.h--This is the header file you generated with Javah, which contains the Java_helloworld_print function prototype.

6. Compile c source code and create native library

Keep in mind that when you create a helloworld.class in Helloworld.java, you include a line of code that loads the native library in your program:

System.loadlibrary ("HelloWorld");

Now that all the necessary C code has been written, you need to compile helloworld.c and create this native library.

Different operating systems support different ways to build native libraries, and on top of Solaris, the following command generates a shared library call libhelloworld.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, rather than a normal Solaris executable file. Because of the page width of this book, I split the line into two lines, you need to enter the command on one line, or put the command in the script. On the WIN32 system, The following command creates 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 will ensure that HelloWorld.dll is already connected to the Win32 multithreaded C library. The-LD option instructs the C compiler to generate a DLL instead of a normal Win32 executable. Of course, in Solaris and Win32, You need to put it in the include path to reflect your own installation configuration.

-i<dir> adds the specified path to the include search path.
If you encounter an error with the cannot open include file: ' jni.h ', the path specifies a problem. There are two solutions:
1. Under your JDK installation directory, there is an include directory that copies the Jawt_md.h and Jni.md.h in the jni.h and Win32 directories to your C compiler's include directory (possibly Vc/include).
2. Specify the correct search path. For example, if my JDK is installed in F:/program files/java/jdk1.6.0_16/, the above parameters are changed to:
-I "F:/program files/java/jdk1.6.0_16/include"-i "F:/program files/java/jdk1.6.0_16/include/win32"
If there are spaces in the directory you want to cause.

7 Running the program

At this point, you have to prepare two components to run the program. The class file (Helloworld.class) invokes the local method, and the native Library (HelloWorld.dll) implements the local method.

Because the HelloWorld class contains its own main method, you can run this program on Solaris or WIN32 operating systems:

Java HelloWorld

You should see the following output:

Hello world!

Setting the correct native library path is very important for the program to run. The native library path is a directory listing that is the search list when the Java virtual machine loads the native library. If you do not set a correct native library path, you will see errors 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 inventory is in the directory of the native library path. If you are running on Solaris, the LD_LIBRARY_PATH environment variable is used to define the native library path. Make sure that it contains a directory name containing the libhelloworld.so Files. If the libhelloworld.so file is in the current directory, you can issue two commands on the standard shell (SH) or KornShell (Ksh) to set the correct LD_LIBRARY_PATH environment variable properties:

Ld_library_path=.
Export Ld_library_path

This is equivalent to the following command in the C shell (CSH or TCSH):

Setenv Ld_library_path.

If you are running on a Windows95 or Windows NT computer, try to make sure that the HelloWorld.dll is in the current directory or in the directory listed in the PATH environment variable.

In the Java 2 SDK 1.2 version, you can also specify the native library path in the Java command line as System Properties, as described below:

Java-djava.library.path=. HelloWorld

The-D command-line option is to set the system properties of the Java platform, setting the Java.library.path property to "." to indicate that the JVM is searching the native library under the current directory.

If this article has any questions, please point out in time, lest cause unnecessary trouble to the later person, greatly appreciated!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.