jni -- Java下调用native C函数




$ cd test_jni
$ cat com/jfo/check.java

package com.jfo;
public class check {
    public native String hello();
static {
System.loadLibrary("test");
}
public static void main(String[] args) {
String s = new check().hello();
System.out.println(s);
}
}

$ javac com/jfo/check.java
$ javah -jni com.jfo.check    // this will generate "com_jfo_check.h" header file.
$ ls

com  com_jfo_check.h  jni

$ cat com_jfo_check.h
/ DO NOT EDIT THIS FILE - it is machine generated /
#include <jni.h>
/ Header for class com_jfo_check /

#ifndef _Included_com_jfo_check
#define _Included_com_jfo_check
#ifdef cplusplus
extern "C" {
#endif
/
Class:     com_jfo_check
Method:    hello
Signature: ()Ljava/lang/String;
/
JNIEXPORT jstring JNICALL Java_com_jfo_check_hello
(JNIEnv
, jobject);

#ifdef
cplusplus
}
#endif
#endif

$ mv com_jfo_check.h  jni/
$ cat jni/test.c
#include <stdio.h>
#include <stdlib.h>
#include "com_jfo_check.h"

JNIEXPORT jstring JNICALL Java_com_jfo_check_hello(JNIEnv env, jobject o)
{
printf("hello in cpp.n");
return (
env)->NewStringUTF(env, "hello world returned.");
}

$ cd jni
$ gcc -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -c test.c
$ gcc -nostdlib -Wl,-soname,libtest.so -Wl,-shared test.o  -o libtest.so

$ cd  ../
$ java -Djava.library.path=jni com/jfo/check

hello in cpp.
hello world returned.

这种方式要求:C函数名于Java中的package+classname一致,如Java_com_jfo_check_hello

为了保持函数名称的不变,如hello,可以用另一种方式调用native C函数,参见这里。

end