我需要从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