標籤:
在Java代碼中通過JNI調用C函數的步驟如下:
第一步:編寫Java代碼
1 class HelloJNI{ 2 native void printHello(); 3 native void printString(String str); 4 5 static {System.loadLibrary("hellojni");} 6 7 public static void main(String args[]) { 8 HelloJNI myJNI = new HelloJNI(); 9 10 myJNI.printHello();11 myJNI.printString("Hello World from c fun");12 13 }14 15 }
第二步: 編譯Java代碼
javac HelloJNI.java 產生HelloJNI.class檔案
第三步: 產生C語言標頭檔
javah HelloJNI 產生HelloJNI.h標頭檔
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class HelloJNI */#ifndef _Included_HelloJNI#define _Included_HelloJNI#ifdef __cplusplusextern "C" {#endif/* * Class: HelloJNI * Method: printHello * Signature: ()V */JNIEXPORT void JNICALL Java_HelloJNI_printHello (JNIEnv *, jobject);/* * Class: HelloJNI * Method: printString * Signature: (Ljava/lang/String;)V */JNIEXPORT void JNICALL Java_HelloJNI_printString (JNIEnv *, jobject, jstring);#ifdef __cplusplus}#endif#endif
第四步: 編寫C代碼
要注意c代碼必須得依照上面標頭檔的方式編寫,和普通的c函數有區別
1 #include"HelloJNI.h" 2 #include<stdio.h> 3 4 JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *env, jobject obj) { 5 printf("Hello World!\n"); 6 return; 7 } 8 9 JNIEXPORT void JNICALL Java_HelloJNI_printString(JNIEnv * env, jobject obj, jstring string) {10 const char *str = (*env)->GetStringUTFChars(env,string,0);11 printf("%s!\n",str);12 return;13 }
第五步: 產生C共用庫
CodeBlocks下:
File - New - Project - Shared library - Go
因為HelloJNI.h中有這樣的一句#include <jni.h>,標準的庫檔案下是沒有這個檔案的,但這個檔案可以在JDK的安裝目錄下面找到
為了能夠順利編譯,需要把相應檔案複製到C編譯器的標頭檔存放處,像下面這樣:
編譯產生C共用庫檔案:
不過CodeBlocks預設產生的檔案前面加了首碼lib,需要手動去掉,但運行是還是出了問題:
1 D:\hixin\C>java HelloJNI2 Exception in thread "main" java.lang.UnsatisfiedLinkError: D:\hixin\C\hellojni.d3 ll: Can‘t load IA 32-bit .dll on a AMD 64-bit platform4 at java.lang.ClassLoader$NativeLibrary.load(Native Method)5 at java.lang.ClassLoader.loadLibrary0(Unknown Source)6 at java.lang.ClassLoader.loadLibrary(Unknown Source)7 at java.lang.Runtime.loadLibrary0(Unknown Source)8 at java.lang.System.loadLibrary(Unknown Source)9 at HelloJNI.<clinit>(HelloJNI.java:5)
大意是產生的dll不是64位的,看了網上最新版的vs似乎是可以產生64位dll,算啦不糾結這個啦
《Android進階》之第一篇 在Java中調用C庫函數