初使JNI

author:lanhxg

original site:https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html

Environment:ubuntu12.04 64bit
ps:  有参考一个哥们的,这个哥们网址忘记了,如有问题可以pm我

 Use JNI with C
Step 1: Write a Java Class that uses C Codes - HelloJNI.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class HelloJNI {
   static {
      System.loadLibrary("HelloJNI"); // Load native library at runtime
                                   // hello.dll (Windows) or libhello.so (Unixes)
   } 
   // Declare a native method sayHello() that receives nothing and returns void
   private native void sayHello(); 
   // Test Driver
   public static void main(String[] args) {
      new HelloJNI().sayHello();  // invoke the native method
   }
}

The static initializer invokes System.loadLibrary() to load the native library "Hello" (which contains the native methodsayHello()) during the class loading. It will be mapped to "hello.dll" in Windows; or"libhello.so" in Unixes. This library shall be included in Java's library path (kept in Java system variablejava.library.path); otherwise, the program will throw a UnsatisfiedLinkError. You could include the library into Java Library's path via VM argument-Djava.library.path=path_to_lib.

Next, we declare the method sayHello() as a native instance method, via keywordnative, which denotes that this method is implemented in another language. A native method does not contain a body. ThesayHello() is contained in the native library loaded.

The main() method allocate an instance of HelloJNI and invoke the native methodsayHello().

Compile the "HelloJNI.java" into "HelloJNI.class".

> javac HelloJNI.java
Step 2: Create the C/C++ Header file - HelloJNI.h

Run javah utility on the class file to create a header file for C/C++ programs:

> javah HelloJNI

The output is HelloJNI.h as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class HelloJNI */
 #ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif/*
 * Class:     HelloJNI
 * Method:    sayHello
 * Signature: ()V
 */JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *, jobject);
 
#ifdef __cplusplus
}
#endif
#endif

The header declares a C function Java_HelloJNI_sayHello as follows:

JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *, jobject);

The naming convention for C function is Java_{package_and_classname}_{function_name}(JNI arguments). The dot in package name shall be replaced by underscore.

The arguments:

  • JNIEnv*: reference to JNI environment, which lets you access all the JNI fucntions.

  • jobject: reference to "this" Java object.

We are not using these arguments in the hello-world example, but will be using them later. Ignore the macrosJNIEXPORT and JNICALL for the time being.

The extern "C" is recognized by C++ compiler only. It notifies the C++ compiler that these functions are to be compiled using C's function naming protocol (instead of C++ naming protocol). C and C++ have different function naming protocols as C++ support function overloading and uses a name mangling scheme to differentiate the overloaded functions. Read "Name Mangling".

Step 3: C Implementation - HelloJNI.c
1
2
3
4
5
6
7
8
9
#include <jni.h>
#include <stdio.h>
#include "HelloJNI.h" 
// Implementation of native method sayHello() of HelloJNI classJNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj) {
   printf("Hello World!\n");
   return;
}


Save the C program as "HelloJNI.c".

The header "jni.h" is available under the "<JAVA_HOME>\include" and "<JAVA_HOME>\include\win32" directories, where<JAVA_HOME> is your JDK installed directory (e.g., "c:\program files\java\jdk1.7.0").

The C function simply prints the message "Hello world!" to the console.

Compile the C program - this depends on the C compiler you used.

For Ubuntu :

> export export LD_LIBRARY_PATH=$PWD
> gcc -I ${JAVA_HOME}/include -I ${JAVA_HOME}/include/linux -fPIC -shared -o libHelloJNI.so HelloJNI.c
> java HelloJNI

You can do all steps as a shell:

#!/bin/sh 
JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:bin/javac::") 
#echo $JAVA_HOME
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD 
echo $LD_LIBRARY_PATH
sfile=$1
append=java
sh_append=so
sh_prefix=lib
jfile=${sfile}.${append}
cfile=${sfile}.c
sharefile=${sh_prefix}${sfile}.${sh_append}
javac $jfile
javah $sfile 
gcc -I ${JAVA_HOME}/include -I ${JAVA_HOME}/include/linux -fPIC -shared -o $sharefile $cfile 
java $sfile

Save above command in a shell file such as  "build.sh"

> chmod a+x build.sh
> ./build.sh HelloJNI

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值