ページ

2014年9月17日水曜日

JNIを使ってみる 1

JNI・・・名前だけは良く聞くJNIを使ってみる

Javaと他の言語とのインターフェースという事なので、AndroidでJavaとCの連携を
実現しているのでJavaとCでやってみる。

・ 大まかな流れ
   1. Javaコードの作成
   2. Javaコードのコンパイル
   3. Cヘッダファイルの生成
   4. Cコードの作成
   5. 共有ライブラリの生成
   6. Javaプログラムの実行


まずはJavaコード
class HelloJNI {
 
  native void printHello();                        // C/C++で作成予定のメソッドを宣言  native void printString(String str);
 
  static {
    System.loadLibrary("hellojni");          // hellojni.dll(Windowsだと)のロード  }
 
  public static void main(String args[]) {
    HelloJNI myJNI = new HelloJNI();
    // ↓実際に使用
    myJNI.printHello();
    myJNI.printString("Hello from printString fun");
  }
}

これをコンパイル
>javac HelloJNI.java

※試しに現時点で実行すると・・・
>java HelloJNI
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hellojni in java.l
ibrary.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
        at java.lang.Runtime.loadLibrary0(Runtime.java:849)
        at java.lang.System.loadLibrary(System.java:1088)
        at HelloJNI.<clinit>(HelloJNI.java:7)
当然ながら怒られる。


次にCヘッダファイル生成。これは便利なツールを使用
>javah HelloJNI

↓ヘッダファイルが生成される
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */
#ifndef _Included_HelloJNI
#define _Included_HelloJNI

#ifdef __cplusplus
extern "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コードを作成
#include "HelloJNI.h"
#include <stdio.h>
/*
 * Class:     HelloJNI
 * Method:    printHello
 * Signature: ()V
 */

JNIEXPORT void JNICALL Java_HelloJNI_printHello
(JNIEnv *env, jobject obj) {
 printf("Hello World!\n");
 return;
}
/*
 * Class:     HelloJNI
 * Method:    printString
 * Signature: (Ljava/lang/String;)V
 */

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;
}

 共有ライブラリの作成
Visual StudioのCross Toolコマンドプロンプトを使う

>cl -I"<JDK_HOME>\include" -I"
<JDK_HOME>\include\win32" -LD HelloJNI.c -Fehellojni.dll
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.
HelloJNI.c
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.
/dll
/implib:hellojni.lib
/out:hellojni.dll
HelloJNI.obj
   ライブラリ hellojni.lib とオブジェクト hellojni.exp を作成中


これでhellojni.dllが作成される。
いざ実行!!
>java HelloJNI
Hello World!
Hello from printString fun!

ちゃんと連携できました^^

0 件のコメント:

コメントを投稿