接着上一篇 JNI Java調用so包相關問題總結,出現了很多問題,按照操作應該不會發生不到so包的錯誤,其實最後出現的也是說加載不到libpython2.7.x.so.1,我就納悶了,怎麼和python扯上關係了? 測試環境的python版本是2.6所以換了臺機器,沒有再出現找不到python的so包問題,取而代之的是無法找到本地方法,原來算法小哥哥是用Cython編譯的so包,原版本是用python寫的ORZ……
現在總結下java調用動態鏈接庫的正確步驟,之前有記過windows版本 JNI HelloWorld的例子 調用的是.dll,這裏再順便記錄下linux版本的
首先編寫好java文件,確定好需要調用的native方法,再生成相應的.h頭文件
public class ATest {
private native void hello();
static{
System.load("/root/jni/lib/libAtest.so");
}
public static void main(String[] args){
ATest test = new ATest();
test.hello();
}
}
執行指令javah -jni -classpath 類目錄 -d 目的目錄 類名
生成的頭文件如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class ATest */
#ifndef _Included_ATest
#define _Included_ATest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: ATest
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_ATest_hello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
再在.c文件中引入頭文件並且實現對應的方法
#include<jni.h>
#include<stdio.h>
#include"ATest.h"
/*
* Class: ATest
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_ATest_hello
(JNIEnv *, jobject){
printf("hello,heqianqian");
}
最後把.c文件打包成so文件(前提是需要安裝完gcc或者g++)
g++ -I"/usr/local/java/jdk1.8.0_121/include/linux" -I"/usr/local/java/jdk1.8.0_121/include" -fpic -shared -o libAtest.so ATest.c
I 選項後面添加的是jdk的include目錄以及include下的linux目錄地址,如果不添加會出現找不到jni.h頭文件以及jni_md.h文件。
編譯完成之後就能產生目的so包,拷貝到指定目錄下,再運行之前的ATest.java文件即可
so文件名 和類名一直,,前綴默認是lib