きったんの頭

JNI

DLL を Java から呼び出すサンプル

Java

Java をビルド (ここでは bin 以下に出力するものとする)

./src/ktn/sample/Jni.java

package ktn.sample;

public class Jni {
    // DLL の読み込み
    static {
        String bit = System.getProperty("sun.arch.data.model");
        try {
            // 32bit/64bit それぞれに対応するDLLが必要
            if ("64".equals(bit)) {
                System.loadLibrary("JniSample_x64");
            } else {
                System.loadLibrary("JniSample_x32");
            }
        } catch (UnsatisfiedLinkError e) {
            // DLLが見つからないなどの例外
            e.printStackTrace();
        }
    }
    
    /**
     * 呼び出すメソッド
     */
    public static native void prints(String[] src);
    
    public static void main(String[] args) {
        prints(args);
    }
}

C

./jni.bat

class からヘッダファイル生成

javah -classpath bin -jni ktn.sample.Jni

ktn_sample_Jni.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class ktn_sample_Jni */

#ifndef _Included_ktn_sample_Jni
#define _Included_ktn_sample_Jni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     ktn_sample_Jni
 * Method:    prints
 * Signature: ([Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_ktn_sample_Jni_prints
  (JNIEnv *, jclass, jobjectArray);

#ifdef __cplusplus
}
#endif
#endif

ktn_sample_Jni.c

#include "ktn_sample_Jni.h"

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT void JNICALL Java_ktn_sample_Jni_prints
    (JNIEnv *env, jclass jc, jobjectArray arr)
{
    jsize i;
    jsize len;
    jobject obj;
    const char *str;

    /* 配列の長さ取得 */
    len = (*env)->GetArrayLength(env, arr);
    
    for (i = 0; i < len; ++i) {
        /* 配列の要素を文字列として取得 */
        obj = (*env)->GetObjectArrayElement(env, arr, i);
        str = (*env)->GetStringUTFChars(env, (jstring)obj, 0);
        
        /* 出力 */
        printf(str);
        printf("\n");
    }
}

#ifdef __cplusplus
}
#endif