首先設好 include 和 lib path,這個網路上資料很多,可自行查找。
錯誤排解:
[1] 發生 Java 異常 EXCEPTION_ACCESS_VIOLATION (0xc0000005):
表示 jvm.dll 位置有誤。
直接指定到 /jre/bin/client/ 去 LoadLibrary 就行,
任何「多餘」的拷貝、指定動作都可能引起此異常。
[2] JNI_CreateJavaVM 傳回 JNI_ERR:
「可能」是先前安裝過多個 JDK 或 JRE 版本,
因未移除,或未移除乾淨,互相干擾所致。
解法是直接 load jvm.dll。
[3] Dev C++ 如何加 -ljvm?
沒時間試驗,但至少 lib path 要設對。
Test.java
public class Test { public static void hello () { System.out.print ("hello~"); } public static void main (String[]s) {} }以 javap -s -p Test 觀察各 method 的 Signature,
供 GetStaticMethodID 識別調用。
#undef UNICODE #pragma comment (lib,"jvm.lib") #include "windows.h" #include "jni.h" #include <iostream> using namespace std; #define CHECK(o) if(o); else{\ cout<<__FILE__<<" ("<<__LINE__<<"): not satisfy "<<#o ;\ exit (getchar());\ } typedef jint (WINAPI* PFunCreateJavaVM) (JavaVM**, void**, void*); int main () { JavaVMOption opt[4] = { {"-Djava.compiler=NONE",0}, {"-Djava.class.path=." ,0}, }; JavaVMInitArgs vm_args = { JNI_VERSION_1_2, 2, opt, JNI_TRUE //opt = JRE 運行參數 }; JNIEnv* env = 0; JavaVM* jvm = 0; HINSTANCE hInst = LoadLibrary ("C:/Java/jre/bin/client/jvm.dll"); CHECK (hInst != 0); PFunCreateJavaVM CreateJavaVM = (PFunCreateJavaVM) GetProcAddress (hInst, "JNI_CreateJavaVM"); CreateJavaVM (&jvm, (void**)&env, &vm_args); CHECK (env != 0); jclass cls = env->FindClass ("Test"); //查找 Java 類別 CHECK (cls != 0); jmethodID pfn = env->GetStaticMethodID (cls, "hello", "()V"); CHECK (pfn != 0); env->CallStaticVoidMethod (cls, pfn); if (env->ExceptionOccurred ()) { env->ExceptionDescribe (); } jvm->DetachCurrentThread (); jvm->DestroyJavaVM (); return getchar(); }
沒有留言:
張貼留言