在Java中調用C

來源:互聯網
上載者:User

標籤:

在Java代碼中通過JNI調用C函數的步驟如下:

第一步:編寫Java代碼

第二步:編譯Java代碼(javac Java檔案)

第三步:產生C代碼標頭檔(javah java類名,自動產生)

第四步:編寫C代碼(實現C代碼標頭檔裡面的函數)

第五步:產生C共用庫(使用工具編譯產生C共用庫,win下面為dll檔案,Linux下面為so檔案)

第六步:運行Java程式(java 類名)

一、編寫Java代碼

首先編寫調用C語言的Java原始碼HelloJNI.java

public class HelloJNI {native void printHello();native void printString(String str);static {System.loadLibrary("hellojni");}public static void main(String[] args) {// TODO Auto-generated method stubHelloJNI myJNI = new HelloJNI();myJNI.printHello();myJNI.printString("Hello world form printString function!");}}

說明:

1. 在Java類中,使用”native”關鍵字,聲明本地方法,該方法與用C/C++編寫的JNI本地函數相對應。”native”關鍵字告知Java編譯器,在Java代碼中帶有該關鍵字的方法只是聲明,具體由C/C++等其它語言編寫實現。

2. 在Java類中聲明了本地方法之後,接下來,調用System.loadLibrary()方法,載入具體實現本地方法的C運行庫(在Java中載入本地運行庫通常使用靜態塊(static block))。System.loadLibrary()方法載入由字串參數指定的本地庫,在不同作業系統平台下,載入的C運行庫不同。在Window下面,調用System.loadLibrary(“hellojni”),則hellojni.dll會被載入;在Linux下面,則會載入libhellojni.so檔案。

二、編譯Java代碼

使用javac編譯java原始碼

javac HelloJNI.java

三、產生C代碼標頭檔

使用javah自動產生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標頭檔中的方法,hellojni.c檔案見下:

#include "HelloJNI.h"#include <stdio.h>JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *env, jobject obj){printf("Hello world!\n");return ;}JNIEXPORT void JNICALL Java_HelloJNI_printString(JNIEnv *env, jobject obj, jstring string){const char * str = (*env)->GetStringUTFChars(env,string,0);printf("%s!\n",str);return ;}

說明:

1、GetStringUTFChars ()是JNI函數,用來將Java字串轉換成C語言字串。JNI提供了多種JNI函數,用來處理C字串與Java字串的轉換,具體參見http://blog.csdn.net/qinjuning/article/details/7595104

五、產生C共用庫

在Linux下測試,書寫makefile檔案,編譯剛才所寫的C代碼,產生.so檔案;

makefile檔案見下:

libhellojni.so:hellojni.o makefilegcc -Wall -rdynamic -shared -o libhellojni.so hellojni.ohellojni.o:hellojni.c HelloJNI.hgcc -Wall -c hellojni.c -I./ -I/usr/lib/jdk/include -I/usr/lib/jdk/include/linux -fPICcl:rm -rf *.o *.so

使用make命令編譯

make

說明:

1、產生的so檔案必須命令為libhellojni.so,與java代碼中的System.loadLibrary("hellojni")對應;

2、在編譯時間,必須加上-fPIC,否則,編譯時間報以下錯誤:

/usr/bin/ld: hellojni.o: relocation R_X86_64_32 against `a local symbol‘ can not be used when making a shared object; recompile with -fPIC
hellojni.o: could not read symbols: Bad value
collect2: ld 返回 1
make: *** [hellojni.so] 錯誤 1

3、gcc和rm前面必須是一個tab空格,否則makefile格式不正確;

六、運行java程式

在運行java程式之前,要把產生的so檔案加入LD_LIBRARY_PATH中,如下:

export LD_LIBRARY_PATH=./

否則,在運行java程式的時候報錯,錯誤資訊見下:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no hellojni in java.library.pathat java.lang.ClassLoader.loadLibrary(ClassLoader.java:1738)at java.lang.Runtime.loadLibrary0(Runtime.java:823)at java.lang.System.loadLibrary(System.java:1028)at HelloJNI.<clinit>(HelloJNI.java:7)Could not find the main class: HelloJNI. Program will exit.

運行java程式:

java HelloJNI

結果見下:

Hello world!Hello world form printString function!!

在Java中調用C

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.