Jni 使用

Java操作:

       定义函数(关键字native): public native void FunctionName(byte arglist1[], char arglist2[], .....);

       Load库文件 : 

1.  System.loadLibrary("Name") 加载在library.path下Name.dll文件,注意linux下.so文件的命名格式是 libName.so,仍然加载("Name")而不是("libName")

2.  System.load("PATH/LibName.dll")  加载在绝对路径下Name.dll

        javac ClassName.java                     生成class文件

        例:javac JniCase.java

        javah Package.ClassName           生成Package_Class.h文件

        例:javah jni.test.JniCase

        java   Package.ClassName           执行程序  -Djava.library.path=指定lib目录

        例:java jni.test.JniCase

 例子JniCase.java:

package jni.test;
public class JniCase {
	public native int CFunction(byte datB[], char datC[], int len);
	
	public static void main(String[] args) {
		System.loadLibrary("TestLib");

        JniCase sample = new JniCase();
		final int DATA_SIZE = 128;
				
		byte datB[] = new byte[DATA_SIZE];
        char datC[] = new char[DATA_SIZE];
		  
	    sample.CFunction(datB, datC, DATA_SIZE);

        // Verification
        int i;
        for (i = 0 ; i < DATA_SIZE ; ++i) {
            if (datB[i] % 16 != datC[i]) {
                break;
            }
        }
	    if (i == DATA_SIZE) {
            System.out.printf("Success!\n");
        } else {
            System.out.printf("Fail!\n");
        }
    }
}

C操作:

       先将JDK下的include和include\win32导入lib工程下,引入javah生成的.h文件,在.h中有函数的定义。

       例: g++ TestLib.cpp -O2 -shared -fPIC -m64 -o libTestLib.so

       注意:1. 函数的命名格式:   Java_Package_Path_FunctionName();

                  2. Java中char size 是2 Byte,Byte才是真正C中的char。

                       typedef unsigned short  jchar;

例子TestLib.cpp:

#include "jni_test_JniCase.h"

JNIEXPORT jint JNICALL Java_jni_test_JniCase_CFunction
  (JNIEnv *env, jobject obj, jbyteArray bArr, jcharArray cArr, jint _size) {

      jbyte *cbArr = env->GetByteArrayElements(bArr, 0);
      jchar *ccArr = env->GetCharArrayElements(cArr, 0);

      for (int i = 0 ; i < _size ; ++i) {
          ccArr[i] = i % 16;
          cbArr[i] = i;
      }
      
      env->ReleaseByteArrayElements(bArr, cbArr, 0);
      env->ReleaseCharArrayElements(cArr, ccArr, 0);
      return 1;
}


        


### JNI使用方法 JNI(Java Native Interface)是一种用于让Java代码与其他编程语言(如C、C++)编写的代码进行交互的技术。以下是关于如何使用JNI实现Java与本地代码交互的具体说明。 #### 定义本地方法 在Java中,可以通过`native`关键字来声明一个本地方法。该方法的实际实现将在本地代码中完成。例如: ```java public class TestLibrary { public native void testPrint(); static { System.loadLibrary("testlibrary"); // 加载本地库 } public static void main(String[] args) { new TestLibrary().testPrint(); // 调用本地方法 } } ``` 上述代码中的`System.loadLibrary()`方法会加载指定名称的本地库文件[^1]。 #### 生成头文件 为了使本地代码能够识别Java类及其方法签名,需要通过`javah`命令生成对应的头文件。假设上面的Java类名为`TestLibrary`,则执行如下命令可生成`.h`文件: ```bash javac TestLibrary.java javah -jni TestLibrary ``` 这将生成一个名为`TestLibrary.h`的头文件,其中包含了供本地代码使用的函数原型[^4]。 #### 编写并实现本地代码 接下来,在C或C++中编写具体的功能逻辑,并将其链接到之前生成的头文件上。下面是一个简单的例子展示如何实现`testPrint`方法: ```cpp #include "com_baidu_xxx_jni_TestLibrary.h" #include <jni.h> #include <iostream> // 实现 sayHello 本地方法 JNIEXPORT void JNICALL Java_com_baidu_xxx_jni_TestLibrary_testPrint(JNIEnv *env, jobject obj) { std::cout << "Print Code C++!" << std::endl; } ``` 此部分实现了由Java端调用的打印操作。 #### 构建共享库 最后一步是构建包含所实现功能的动态库。对于不同平台来说,最终产物可能是`.dll`(Windows), `.so`(Linux/Unix)或者`.dylib`(macOS)。通常情况下,可以借助像Makefile这样的工具自动化这一过程。 --- ### 注意事项 - **性能考虑**:虽然JNI提供了强大的跨语言能力,但它也可能带来额外开销。因此只应在必要时才采用这种方式。 - **异常处理**:当从原生层抛出错误时,应妥善管理这些情况以免影响整个应用程序稳定性[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值