我需要從Java程序中調用some methods in Wininet.dll。從Java調用Win32 API方法
我可以找到大量關於如何調用從Java創建的新DLL的教程,但似乎找不到有關如何從Java調用已經存在的DLL的教程。
我知道這涉及到JNI,但是我該怎麼做呢?我需要在Wininet.h上調用javah
嗎?我在哪裏可以獲得Wininet.h的副本?一個指向現有的,詳細教程就足夠了。
我需要從Java程序中調用some methods in Wininet.dll。從Java調用Win32 API方法
我可以找到大量關於如何調用從Java創建的新DLL的教程,但似乎找不到有關如何從Java調用已經存在的DLL的教程。
我知道這涉及到JNI,但是我該怎麼做呢?我需要在Wininet.h上調用javah
嗎?我在哪裏可以獲得Wininet.h的副本?一個指向現有的,詳細教程就足夠了。
JNA似乎你想要什麼the industry standard,「提供Java程序方便地訪問本地共享庫(在Windows DLL)的無寫什麼,但基於Java的代碼沒有JNI或本機代碼需要」
還有Java Foreign Function Interface - example usage
如果是確定FO R您,您可以embed的JRuby解釋,並通過jruby-ffi至極是一個容易得多調用WINAPI,見here,here和here
不能直接調用本地庫:這是因爲Java本地接口不支持方法中的某些參數。
有一種叫GlueGen的東西,它會創建一個獨立的二進制文件,它將動態鏈接到你的本地DLL。生成的二進制文件與JNI兼容,因此可以從Java中調用。
http://en.wikipedia.org/wiki/Gluegen
爲了得到一個頭文件的wininet.dll文件,你可能需要有平臺SDK(或Windows SDK,最新版本)。您還可以在網上搜索包含此頭文件的聯機存儲庫。
GlueGen需要一個頭文件,一個ANSI C編譯器等
還有一個不太爲人所知的庫調用NativeCall,不需要GlueGen。它已經有兼容Java的二進制文件。這顯然比較慢,因爲它會根據Java的請求動態加載DLL。我沒有使用過這一點,但是,但是聽起來前途:
我不得不這樣做一會兒前。你需要一個C編譯器和Windows頭文件。我使用了mingw,因爲它是免費的,我只編譯一個小文件。
首先你要上你的課。這裏有一個例子:
package org.whatever.thingy;
public class MyClass {
// Here is a JNI method, identified by 'native'
public static native callWin32Thingy(int x, int y, boolean z);
/* At this point, normal class stuff, other methods, variables, whatever */
}
你然後用自帶的JDK中的命令,它會自動把你的類,並生成h和.c文件之一。該命令是「javah」。方法簽名將如下所示:
JNIEXPORT void JNICALL Java_com_whatever_1thingy_MyClass_callWin32Thingy
(JNIEnv *, jclass, jint, jint, jboolean);
在.c文件中,可以包含任何需要的窗口標頭,並充實該方法。
JNIEXPORT void JNICALL Java_com_whatever_1thingy_MyClass_callWin32Thingy
(JNIEnv *a, jclass b, jint c, jint d, jboolean e) {
// Prep steps....
Win32MethodCallWeCareAbout(x, y, z, hWhatever);
// Cleanup stuff...
}
這是非常重要不重命名的方法,這就是它被如何與您的特定類關聯。
一旦你得到了,你將這些文件編譯成一個DLL。這裏是我用於mingw的命令,你必須調整類/路徑/等。
c:/MinGW/bin/gcc -c -Ic:/MinGW/include -I"c:/Program Files/Java/jdk1.5.0_12/include"
-I"c:/Program Files/Java/jdk1.5.0_12/include/win32" -D__int64="long long"
com_whatever_thingy_MyClass_JNIHelper.c
c:/MinGW/bin/gcc -shared -o JNIHelper.dll
com_whatever_thingy_MyClass_JNIHelper_JNIHelper.o
-Wl,--add-stdcall-alias,--kill-at,--output-def,def_file
這將產生一些文件,包括JNIHelper.dll,這就是我命名我的DLL。
在這一點上,你基本上完成了。您正常使用Java類,並在調用靜態方法時運行Win32代碼。你所要做的就是導入庫。某處在你的代碼(我把它放在一個靜態塊在我的課),你需要這條線:
System.loadLibrary("JNIHelper");
這將導致Java來加載一個名爲「JNIHelper.dll」庫,並將其鏈接到代碼。它必須位於Java知道的圖書館路徑的某個地方。
就是這樣。這是一堆樣板,但如果你正在做一些簡單的包裝,很容易。如果你不得不處理Java類型或分配內存,情況會變得更糟(注意:我沒有,所以我沒有經驗)。
有一個完整的教程here(第一,我發現今天看起來體面的,你可以在網絡上找到他人。在Wikipedia文章JNI有更多的信息了。
希望這有助於。
你不需要Java類中的「native」關鍵字嗎? – 2010-03-06 12:24:11
@Thorbjørn:你的權利,我錯過了,謝謝。編輯添加。 – MBCook 2010-03-06 19:37:36
這需要一個凹凸 - JNA遠遠優於純JNI,用於本地庫訪問 – 2010-03-05 19:47:28
+1:JNA是不錯的選擇雖然你需要弄清楚如何在Java中映射函數簽名,但我最近使用JNA與藍牙設備通過原生的Win32 API – wierob 2010-03-05 20:06:44
JNA非常漂亮當我在一週的工作中向一位朋友解釋它時,我竟然竟然告訴他這是「魔術」。 – rob 2010-03-06 00:40:04