ユーザ用ツール

サイト用ツール


java:jni

JNI

C等で作成したOSネイティブのライブラリを呼び出す技術。JNIから呼べるのはJNI用に作成されたライブラリのみ。WindowsではJNIでは、JNI用に作られたDLLしか操作できず、通常のDLLを直接Javaから操作することはできない。Windows APIを使うには、JNI用に作成されたDLLを呼び出し、JNIのDLLの中からネイティブAPIを呼び出す。

サンプルコード

ODBCCP32というDLLを操作してODBCデータソースを作成する。

Javaのソースを書く

package jp.paulownia.odbc;
 
public class JOdbccp32 {
    /** クラスロード時にDLLもロードします。 */
    static {
        System.loadLibrary("JOdbccp32");
    }
 
    /** ユーザーデータソースの追加 */
    public static final short ODBC_ADD_DSN = 1; 
 
    /** ユーザーデータソースの編集 */
    public static final short ODBC_CONFIG_DSN = 2;
 
    /** ユーザーデータソースの削除 */
    public static final short ODBC_REMOVE_DSN = 3;
 
    /** システムデータソースを追加 */
    public static final short ODBC_ADD_SYS_DSN = 4;
 
    /** システムデータソースを編集 */
    public static final short ODBC_CONFIG_SYS_DSN = 5; 
 
    /** システムデータソースを削除 */
    public static final short ODBC_REMOVE_SYS_DSN = 6;
 
    /** デフォルトDSNを削除 */
    public static final short ODBC_REMOVE_DEFAULT_DSN = 7;
 
    /** SQLConfigDataSource関数を呼び出します。 */
    public native boolean callSQLConfigDataSource(short op, String driver, String dsn);
}

javacでコンパイル。

C:¥javaSrc¥jni> javac jp/paulownia/odbc/JOdbccp32.java

生成したクラスからC言語用のヘッダファイルを作成します。

C:¥javaSrc¥jni> javah -jni jp.paulownia.odbc.JOdbccp32

上記のコマンドでjp_paulownia_odbc_JObbccp32.hというファイルが作られる(ファイル名はクラスに合わせて変わる)。このヘッダファイルを使ってC++でJOdbccp32.dllを作成する。 dllの作成方法は、こちらのサイト等を参考にする。C++のソースは以下のようになる。

#include "jp_paulownia_odbc_JOdbccp32.h"
#include <windows.h>
#include <odbcinst.h>
#include <stdio.h>
 
 
JNIEXPORT jboolean JNICALL Java_jp_paulownia_odbc_JOdbccp32_callSQLConfigDataSource
    (JNIEnv *env, jobject jobj, jshort op, jstring db, jstring dsn) {
 
    int dsnLen = env->GetStringLength(dsn);
    char* cDsn = (char*)calloc(dsnLen * 2 + 1, sizeof(char));
    const jchar* jcDsn = env->GetStringChars(dsn, NULL);
    WideCharToMultiByte(CP_ACP, 0, jcDsn, dsnLen, cDsn, dsnLen * 2 + 1, NULL, NULL);
    env->ReleaseStringChars(dsn, jcDsn);
 
    int dbLen = env->GetStringLength(db);
    char* cDb = (char*)calloc(dbLen * 2 + 1, sizeof(char));
    const jchar* jcDb = env->GetStringChars(db, NULL);
    WideCharToMultiByte(CP_ACP, 0, jcDb, dbLen, cDb, dbLen * 2 + 1, NULL, NULL);
    env->ReleaseStringChars(db, jcDb);
 
    BOOL rtn = SQLConfigDataSource(NULL, op, cDb, cDsn);
    free(cDb);
    free(cDsn);
    return rtn;
}

作成したdllをカレントディレクトリに設置し、テストコードを実行。

import jp.paulownia.odbc.JOdbccp32;
public class Test {
    public static void main(String[] hoge) {
        JOdbccp32 odbc = new JOdbccp32();
        String dsn = "DSN=ac¥0Description=pos data sample¥0DBQ=c:¥¥javaSrc¥¥pos.mdb";
        String driver = "Microsoft Access Driver (*.mdb)";
        odbc.callSQLConfigDataSource(JOdbccp32.ODBC_ADD_DSN, driver, dsn);
    }
}

実行する。

C:¥javaSrc¥jni> java Test
true

Access用の新しいODBCデータソースがユーザDSNに作成される。Access以外にもSQL ServerなどのODBCデータソースも作ることができる。

2バイト文字や特殊文字を扱うのが多少面倒。1バイト文字だけならば、jstringからchar*への変換は、GetStringUTFChars関数を使えば良い。しかし、JavaのStringがヌル文字(¥0)などの特殊文字や2バイト文字を含む場合、上記のようにGetStringChars関数を使ってwcharとして取得し、charに変換しなければならないようだ。当然だがC++をしっかり学習しないと何もできない。

MacOSXでのJNI開発

java/jni.txt · 最終更新: 2007/08/28 13:45 by 127.0.0.1