Archive for the ‘JNI’ Category
-
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 ); } }
C ヘッダファイル作成
C:¥> javah -jni Hello
ソースコード(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
ソースコード(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; }
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:¥> javac Hello.java C:¥> java Hello
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(JNI) World! --------------------------- OK ---------------------------
-
Hello, JNI World!
Posted on 4月 10th, 2012 by cx20
JNI
JNA(Java Native Interface)は、Java と他の言語のインターフェイス仕様である。
Java から C言語のライブラリの呼び出し、また、C言語から Java のライブラリの呼び出し等が可能である。
ここでは、C言語から Java のライブラリの呼び出しのサンプルを記載する。ソースコード(呼び出す側(C++))
#include <jni.h> int main( int argc, char* argv[] ) { JNIEnv* env; JavaVM* jvm; // Java VM オプション設定 JavaVMOption options[1]; options[0].optionString = "-Xmx128m"; JavaVMInitArgs vm_args; vm_args.version = JNI_VERSION_1_6; vm_args.options = options; vm_args.nOptions = 1; // Java VM 作成 JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args); // Class 検索 jclass clazz = env->FindClass("Hello"); // Method ID 取得 jmethodID mid = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V"); // Class メソッド呼び出し env->CallStaticVoidMethod(clazz, mid, NULL); // Java VM 破棄 jvm->DestroyJavaVM(); return 0; }
ソースコード(呼び出される側(Java))
public class Hello { public static void main( String[] args ) { System.out.println( "Hello, JNI World!" ); } }
コンパイル&実行方法
$ javac Hello.java $ c++ -o jnihello jnihello.cpp ¥ -I/System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/ ¥ -framework JavaVM ¥ -m64 $ ./jnihello
実行結果
Hello, JNI World!