Java JNI调用c/c++程序

来源:互联网 发布:unity3d宣传片 编辑:程序博客网 时间:2024/06/06 07:27
  1. 创建带native的Java类 eg:Sample1.java
class Sample1 {    // --- Native methods    public native int intMethod(int n);    public native boolean booleanMethod(boolean bool);    public native String stringMethod(String text);    public native int intArrayMethod(int[] intArray);    // --- Main method to test our native library    public static void main(String[] args) {        System.loadLibrary("Sample1");        Sample1 sample = new Sample1();        int square = sample.intMethod(5);        boolean bool = sample.booleanMethod(true);        String text = sample.stringMethod("java");        int sum = sample.intArrayMethod(new int[] {1, 1, 2, 3, 5, 8, 13});        System.out.println("intMethod: " + square);        System.out.println("booleanMethod: " + bool);        System.out.println("stringMethod: " + text);        System.out.println("intArrayMethod: " + sum);    }}

2. 保存编译, 会生成Sample1.class

javac Sample1.java

3. 使用javah 命令生成头文件,此时会出现 Sample1.h文件

javah Sample1//Sample1.h文件内容为:* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class Sample1 */#ifndef _Included_Sample1#define _Included_Sample1#ifdef __cplusplusextern "C" {#endif/* * Class:     Sample1 * Method:    intMethod * Signature: (I)I */JNIEXPORT jint JNICALL Java_Sample1_intMethod  (JNIEnv *, jobject, jint);/* * Class:     Sample1 * Method:    booleanMethod * Signature: (Z)Z */JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod  (JNIEnv *, jobject, jboolean);/* * Class:     Sample1 * Method:    stringMethod * Signature: (Ljava/lang/String;)Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_Sample1_stringMethod  (JNIEnv *, jobject, jstring);/* * Class:     Sample1 * Method:    intArrayMethod * Signature: ([I)I */JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod  (JNIEnv *, jobject, jintArray);#ifdef __cplusplus}#endif#endif</jni.h>

4. 创建本地实现,新建C源码文件,Sample1.cpp

#include "Sample1.h"#include <ctype.h>#include <string.h>// Mutate array to uppercasevoid uppercase(char* str) {    size_t n = strlen(str);    for (size_t i = 0; i < n; i++) {        str[i] = toupper(str[i]);     }}JNIEXPORT jint JNICALL Java_Sample1_intMethod(JNIEnv* env, jobject obj, jint num) {    return num * num;}JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod(JNIEnv* env, jobject obj, jboolean boolean) {    return !boolean;}JNIEXPORT jstring JNICALL Java_Sample1_stringMethod(JNIEnv* env, jobject obj, jstring string) {    const char* str = env->GetStringUTFChars(string, 0);    char cap[128];    strcpy(cap, str);    env->ReleaseStringUTFChars(string, str);    uppercase(cap);    return env->NewStringUTF(cap);}JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod(JNIEnv* env, jobject obj, jintArray array) {    int sum = 0;    jsize len = env->GetArrayLength(array);    jint* body = env->GetIntArrayElements(array, 0);    for (int i = 0; i < len; i++) {        sum += body[i];    }    env->ReleaseIntArrayElements(array, body, 0);    return sum;}

5. 接下来对c++文件进行编译,生成函数库。库有静态库动态库之分。静态库是以.a结尾的文件,例如:libXXX.a;动态库是以.so结尾的文件,例如: libXXX.so

比如,要编译生成动态链接库时:

gcc -c -fpic Sample1.cpp         //会生成Sample1.o的中间文件gcc -shared Sample1.o -o libSample1.so//或者直接;gcc -fpic -shared Sample1.c -o libSample1.so

完成之后就会生成动态链接库:libSample1.so
需要注意的是:
Java JNI的头文件 jni.h需要在两个地方包含:
其一:$JAVA_HOME/include
其二:$JAVA_HOME/include/linux
6.运行java程序:

//pwd 为包含libSample1.so文件的路径。java -Djava.library.path=$(pwd) -cp . Sample1
0 0
原创粉丝点击