jni的使用实例

本文通过一个具体实例展示了如何使用Java Native Interface (JNI) 进行Java与C语言的交互。包括DLL加载、本地方法调用、字符串操作、数组修改及自定义类的读写等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自己参考网上资料写的一些有代表性的实例,仅供参考。

 

没啥说的,测试类

package hellonative;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

/**
 *
 * @author lan
 */
public class Main {

    static {
        try {
            InputStream inputStream = Main.class.getResourceAsStream("HelloNative.dll");
//            System.out.println(inputStream);
            File temporaryDll = File.createTempFile("HelloNative", ".dll");
//            System.out.println(temporaryDll.getAbsolutePath());
            FileOutputStream outputStream = new FileOutputStream(temporaryDll);
            byte[] array = new byte[8192];
            int i = -1;
            while ((i = inputStream.read(array)) != -1) {
                outputStream.write(array, 0, i);
            }
            outputStream.close();
            temporaryDll.deleteOnExit();
            System.out.println(temporaryDll.getAbsolutePath());
            System.load(temporaryDll.getPath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Main m = new Main();
        m.nativePrint();

        m.sayHello("世界");

        System.out.println(m.sayFromC());

        System.out.println(m.addition(10, -5));

        System.out.println(m.isEqual(10, 1));

        String[] array = new String[6];
        for (String s : m.changeStringArray(array)) {
            System.out.print(s + "  ");
        }
        System.out.println();

        int[] is = new int[14];
        for (int i : m.changeIntArray(is)) {
            System.out.print(i + "  ");
        }
        System.out.println();

        Commons c = new Commons(111, "who?");
        m.readObject(c);
        System.out.println(c);

        c = m.writeObject();
        System.out.println(c);
    }

    private native void nativePrint();

    private native void sayHello(String hello);

    private native String sayFromC();

    private native int addition(int a, int b);

    private native boolean isEqual(float a, float b);

    private native int[] changeIntArray(int[] array);

    private native String[] changeStringArray(String[] array);

    private native void readObject(Commons com);

    private native Commons writeObject();
}

 头文件就不用说了

实现的c文件,字段签名可以用javap -s 类全名(包和类名)查看,感觉和反射差不多

#include <jni.h>
#include <stdio.h>
#include "Hello.h"

JNIEXPORT void JNICALL Java_hellonative_Main_nativePrint
(JNIEnv * env, jobject obj) {
    printf("Hello from c.\n");
}

JNIEXPORT void JNICALL Java_hellonative_Main_sayHello
(JNIEnv * env, jobject obj, jstring hello) {
    char* str;
    str = (char*) (*env)->GetStringUTFChars(env, hello, NULL);
    printf("Hello %s from c.\n", str);
    (*env)->ReleaseStringUTFChars(env, hello, str);
}

JNIEXPORT jstring JNICALL Java_hellonative_Main_sayFromC
(JNIEnv * env, jobject obj) {
    char* str = "c say hello 世界";
    return (*env)->NewStringUTF(env, str);
}

JNIEXPORT jint JNICALL Java_hellonative_Main_addition
(JNIEnv * env, jobject obj, jint a, jint b) {
    int i = a;
    int j = b;
    return (jint) i + j;
}

JNIEXPORT jboolean JNICALL Java_hellonative_Main_isEqual
(JNIEnv * env, jobject obj, jfloat a, jfloat b) {
    float i = a;
    float j = b;
    float k = i - j;
    if (k == 0) {
        return (jboolean) 1;
    }
    return (jboolean) 0;
}

JNIEXPORT jintArray JNICALL Java_hellonative_Main_changeIntArray
(JNIEnv * env, jobject obj, jintArray jia) {
    int length = (*env)->GetArrayLength(env, jia);
    int i = 0;
    int k[length];
    jintArray array = (*env)->NewIntArray(env, length);
    for (i = 0; i < length; i++) {
        k[i] = i * 10;
    }
    (*env)->SetIntArrayRegion(env, array, 0, length, k);
    return array;
}

JNIEXPORT jobjectArray JNICALL Java_hellonative_Main_changeStringArray
(JNIEnv * env, jobject obj, jobjectArray joa) {
    int length = (*env)->GetArrayLength(env, joa);
    int i = 0;
    jclass oc = (*env)->FindClass(env, "java/lang/String");
    jobjectArray array = (*env)->NewObjectArray(env, length, oc, 0);
    for (i = 0; i < length; i++) {
        char* str = "Hello";
        jstring s = (*env)->NewStringUTF(env, str);
        (*env)->SetObjectArrayElement(env, array, i, s);
    }
    return array;
}

JNIEXPORT void JNICALL Java_hellonative_Main_readObject
(JNIEnv * env, jobject obj, jobject commons) {
    jclass class = (*env)->GetObjectClass(env, commons); //or FindClass();

    jfieldID fid = (*env)->GetFieldID(env, class, "id", "I");
    jmethodID mid = (*env)->GetMethodID(env, class, "setName", "(Ljava/lang/String;)V");
    int value = (*env)->GetIntField(env, commons, fid);
    printf("id is %d\n", value);
    (*env)->SetIntField(env, commons, fid, 10);
    jstring s = (*env)->NewStringUTF(env, "Hello");
    (*env)->CallVoidMethod(env, commons, mid, s);
    (*env)->ReleaseStringUTFChars(env, s, (*env)->GetStringUTFChars(env, s, 0));
}

JNIEXPORT jobject JNICALL Java_hellonative_Main_writeObject
(JNIEnv * env, jobject obj) {
    jclass class = (*env)->FindClass(env, "hellonative/Commons");
    jmethodID mid = (*env)->GetMethodID(env, class, "<init>", "(ILjava/lang/String;)V");
    const char* str = "这是what?";
    jstring s = (*env)->NewStringUTF(env, str);
    jobject o = (*env)->NewObject(env, class, mid, 100, s);
    (*env)->ReleaseStringUTFChars(env, s, str);
    return o;
}

 

这个就是Commons文件了

package hellonative;

/**
 *
 * @author lan
 */
public class Commons {

    private int id;
    private String name;

    public Commons(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Commons[id:" + id + ",name:" + name + "]";
    }
}

 最后是运行结果了

G:\Users\lan\AppData\Local\Temp\HelloNative461556334708685656.dll
c say hello 世界
5
false
Hello  Hello  Hello  Hello  Hello  Hello  
0  10  20  30  40  50  60  70  80  90  100  110  120  130  
Commons[id:10,name:Hello]
Commons[id:100,name:这是what?]
Hello from c.
Hello 世界 from c.
id is 111
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值