java jni挪用c函數實例分享(java挪用c函數)。本站提示廣大學習愛好者:(java jni挪用c函數實例分享(java挪用c函數))文章只能為提供參考,不一定能成為您想要的結果。以下是java jni挪用c函數實例分享(java挪用c函數)正文
從C/C++到Java,再從Java回到C/C++,明天終究無機會懂得了銜接Java、C/C++的橋梁——JNI。哈哈!分享一下!
1、簡介
JNI是Java native interface的簡寫,可以譯作Java原生接口。Java可以經由過程JNI挪用C/C++的庫,這關於那些對機能請求比擬高的Java法式或許Java沒法處置的義務無疑是一個很好的方法。
2、目標:Java代碼中挪用C/C++代碼
3、完成:假定我們的Java法式為J2C.java, C法式為J2C.c, Java與C之間的通訊函數名為write2proc;
那末write2proc的聲明位於J2C.java,完成位於J2C.c;
4、操作
1. 編寫並編譯Java法式
javac J2C.java => J2C.class
2. 生成C/C++頭文件
javah J2C => J2C.h (裝置JDK後,$JAVA_HOME應當已參加$PATH, 不然應用相對途徑,例如/usr/bin/javah)
3. 編寫對應的C/C++法式:J2C.c
4. 生成C/C++目的文件
gcc -I/usr/lib/jvm/java-6-openjdk-amd64/include -I/usr/lib/jvm/java-6-openjdk-amd64/include/linux -fPIC -c J2C.c => J2C.o
5. 生成C/C++同享庫
gcc -shared -Wl,-soname,libj2c.so.1 -o libj2c.so.1.0 J2C.o => libj2c.so.1.0
6. 重定名cp libj2c.so.1.0 libj2c.so => libj2c.so
7. 將同享庫參加靜態鏈接庫的途徑(此例為以後目次)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
8. 履行Java法式,完成跨說話通訊
java J2C
5、詳細進程
1. 編寫並編譯J2C.java
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
public class J2C
{
static
{
try{
// 此處即為當地辦法地點鏈接庫名
System.loadLibrary("j2c");
} catch(UnsatisfiedLinkError e)
{
System.err.println( "Cannot load J2C library:\n " +
e.toString() );
}
}
//聲明的當地辦法
public static native int write2proc(int pid);
public static void main(String[] args){
//獲得本過程(即主線程)的pid
final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
final String info = runtime.getName();
final int index = info.indexOf("@");
if (index != -1) {
final int pid = Integer.parseInt(info.substring(0, index));
System.out.println(info);
System.out.println(pid);
write2proc(pid);
}
try{
Thread.sleep(8000);
} catch(InterruptedException e){
e.printStackTrace();
}
}
}
note:Java法式中System.loadLibrary參數名表現要載入的C/C++同享庫,第6步生成的同享庫名必需與該參數分歧,即System.loadLibrary(Name) 對應同享庫名libName.so (同享庫名必需以lib開首)
2. 生成C頭文件J2C.h:javah J2C
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class J2C */
#ifndef _Included_J2C
#define _Included_J2C
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: J2C
* Method: write2proc
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_J2C_write2proc
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
note:1. 頭文件主動生成,不要修正它;
2. 函數JNIEXPORT jint JNICALL Java_J2C_write2proc(JNIEnv *, jclass, jint);
依照正文的解釋是在J2C.java文件的類J2C的辦法write2proc處界說,故C法式的完成函數必需與該處簽名分歧;
3. 編寫C法式J2C.c
#include <stdio.h>
#include "J2C.h"
JNIEXPORT int JNICALL Java_J2C_write2proc(JNIEnv * env, jobject arg, jint pid)
{
printf("current pid is %d\n", pid);
return 0;
}
4. 編譯C法式
由於C法式裡#include "J2C.h"而J2C.h又#include <jni.h>, 而gcc外面默許情況其實不曉得jni.h是甚麼器械,故編譯時須要告知編譯器jni.h的地位( jni.h在jdk 的$JAVA_HOME/include上面),所以才有了下面的編譯參數;
由於應用gcc編譯獲得靜態庫,在jni挪用的時刻,某些情形會有異常, 可測驗考試改用g++。
總結
1. Java中辦法的原型聲明與C/C++對應的完成文件界說必需分歧(可以經由過程主動生成的C/C++頭文件來比擬),特別是類名和辦法名;
2. Java中System.loadLibrary()載入的同享庫名必需與前面C/C++生成的同享庫名分歧。
"external storage dir not found");2,保留為文件
public boolean logWeight(Intent batteryChangeIntent) {
Log.i(TAG, "logBattery");
if (batteryChangeIntent == null)
return false;
try {
FileWriter out = null;
if (mWeightLogFile != null) {
try {
out = new FileWriter(mWeightLogFile, true);
}
catch (Exception e) {}
}
if (out == null) {
File root = Environment.getExternalStorageDirectory();
if (root == null)
throw new Exception("external storage dir not found");
mWeightLogFile = new File(root,WeightService.LOGFILEPATH);
boolean fileExists = mWeightLogFile.exists();
if (!fileExists) {
if(!mWeightLogFile.getParentFile().mkdirs()){
Toast.makeText(this, "create file failed", Toast.LENGTH_SHORT).show();
}
mWeightLogFile.createNewFile();
}
if (!mWeightLogFile.exists()) {
Log.i(TAG, "out = null");
throw new Exception("creation of file '"+mWeightLogFile.toString()+"' failed");
}
if (!mWeightLogFile.canWrite())
throw new Exception("file '"+mWeightLogFile.toString()+"' is not writable");
out = new FileWriter(mWeightLogFile, true);
if (!fileExists) {
String header = createHeadLine();
out.write(header);
out.write('\n');
}
}
Log.i(TAG, "out != null");
String extras = createBatteryInfoLine(batteryChangeIntent);
out.write(extras);
out.write('\n');
out.flush();
out.close();
return true;
} catch (Exception e) {
Log.e(TAG,e.getMessage(),e);
return false;
}
}