Hello, Win32 API(JNI) World!
Posted on 5月 3rd, 2012 by cx20
Win32 API(JNI)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は JNI(Java Native Interface)による呼出し例である。
Java からは 直接、Win32 API を呼び出すことは出来ないが、JNI 用の DLL を作成することで呼び出すことが可能となっている。
ソースコード(Java)
import java.io.*;
public class Hello {
static {
System.loadLibrary("Hello");
}
public native int MessageBox( int hwnd, String text, String title, int type );
public static void main(String args[]) {
Hello hello = new Hello();
hello.MessageBox( 0, "Hello, Win32 API(JNI) World!", "Hello, World!", 0 );
}
} |
import java.io.*;
public class Hello {
static {
System.loadLibrary("Hello");
}
public native int MessageBox( int hwnd, String text, String title, int type );
public static void main(String args[]) {
Hello hello = new Hello();
hello.MessageBox( 0, "Hello, Win32 API(JNI) World!", "Hello, World!", 0 );
}
}
C ヘッダファイル作成
ソースコード(C ヘッダファイル)
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Hello */
#ifndef _Included_Hello
#define _Included_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Hello
* Method: MessageBox
* Signature: (ILjava/lang/String;Ljava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_Hello_MessageBox
(JNIEnv *, jobject, jint, jstring, jstring, jint);
#ifdef __cplusplus
}
#endif
#endif |
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Hello */
#ifndef _Included_Hello
#define _Included_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Hello
* Method: MessageBox
* Signature: (ILjava/lang/String;Ljava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_Hello_MessageBox
(JNIEnv *, jobject, jint, jstring, jstring, jint);
#ifdef __cplusplus
}
#endif
#endif
ソースコード(C 実装ファイル)
#include "Hello.h"
#include <windows.h>
/*
* Class: Hello
* Method: MessageBox
* Signature: (ILjava/lang/String;Ljava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_Hello_MessageBox
(JNIEnv* env, jobject me, jint hwnd, jstring text, jstring caption, jint type)
{
#ifdef UNICODE
const jchar* _text = env->GetStringChars(text, 0);
const jchar* _caption = env->GetStringChars(caption, 0);
const int result = MessageBoxW(NULL, (LPCWSTR)_text, (LPCWSTR)_caption, type);
env->ReleaseStringChars(text, _text);
env->ReleaseStringChars(caption, _caption);
#else
/* このコードはマルチバイト文字(MBCS)を考慮していない為、全角文字列を渡した場合に文字化けする。正しくは SJIS に変換する処理が必要。*/
const char* _text = env->GetStringUTFChars(text, 0);
const char* _caption = env->GetStringUTFChars(caption, 0);
const int result = MessageBoxA(NULL, (LPCSTR)_text, (LPCSTR)_caption, type);
env->ReleaseStringUTFChars(text, _text);
env->ReleaseStringUTFChars(caption, _caption);
#endif
return result;
} |
#include "Hello.h"
#include <windows.h>
/*
* Class: Hello
* Method: MessageBox
* Signature: (ILjava/lang/String;Ljava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_Hello_MessageBox
(JNIEnv* env, jobject me, jint hwnd, jstring text, jstring caption, jint type)
{
#ifdef UNICODE
const jchar* _text = env->GetStringChars(text, 0);
const jchar* _caption = env->GetStringChars(caption, 0);
const int result = MessageBoxW(NULL, (LPCWSTR)_text, (LPCWSTR)_caption, type);
env->ReleaseStringChars(text, _text);
env->ReleaseStringChars(caption, _caption);
#else
/* このコードはマルチバイト文字(MBCS)を考慮していない為、全角文字列を渡した場合に文字化けする。正しくは SJIS に変換する処理が必要。*/
const char* _text = env->GetStringUTFChars(text, 0);
const char* _caption = env->GetStringUTFChars(caption, 0);
const int result = MessageBoxA(NULL, (LPCSTR)_text, (LPCSTR)_caption, type);
env->ReleaseStringUTFChars(text, _text);
env->ReleaseStringUTFChars(caption, _caption);
#endif
return result;
}
Win32 データ型と JNI データ型の対応は主に以下のようになっている。
Win32 データ型 |
C/C++ データ型 |
JNI データ型 |
Java データ型 |
BOOL |
int |
jboolean |
boolean |
BYTE |
char |
jbyte |
byte |
WCHAR |
wchar_t |
jchar |
char |
SHORT |
short |
jshort |
short |
INT |
int |
jint |
int |
LONGLONG |
__int64 |
jlong |
long |
FLOAT |
float |
jfloat |
float |
DOUBLE |
double |
jdouble |
double |
VOID |
void |
void |
void |
LPCSTR |
const char * |
jstring |
string |
LPCWSTR |
const wchar_t * |
jstring |
string |
なお、jstring については、使用時に、正しい C/C++ データ型(ANSI, MBCS / UNICODE)に適宜、変換する必要がある。
DLL作成(Visual C++)
C:¥> SET INCLUDE=%JAVA_HOME%include;%JAVA_HOME%includewin32;%INCLUDE%
C:¥> cl Hello.cpp /LD /link user32.lib |
C:¥> SET INCLUDE=%JAVA_HOME%include;%JAVA_HOME%includewin32;%INCLUDE%
C:¥> cl Hello.cpp /LD /link user32.lib
コンパイル&実行方法
C:¥> javac Hello.java
C:¥> java Hello |
C:¥> javac Hello.java
C:¥> java Hello
実行結果
---------------------------
Hello, World!
---------------------------
Hello, Win32 API(JNI) World!
---------------------------
OK
--------------------------- |
---------------------------
Hello, World!
---------------------------
Hello, Win32 API(JNI) World!
---------------------------
OK
---------------------------
Tags: Win32 API
Categories: Java, JNI, library, Win32 API