从Java调用Win32 API方法

我需要从Java程序中调用Wininet.dll中的一些方法 。

我可以find很多关于如何调用从Java创build的新DLL的教程,但似乎找不到有关如何从Java调用已经存在的DLL的教程。

我知道这涉及到JNI,但是我到底该怎么做呢? 我需要在Wininet.h上调用javah吗? 我在哪里得到一个Wininet.h的副本? 指向现有的详细教程的指针就足够了。

  1. JNA似乎是你想要的行业标准 ,“它提供Java程序轻松访问本地共享库(Windows上的DLL),无需编写任何东西,而是Java代码 – 不需要JNI或本地代码”

  2. 还有Java外部函数接口 – 示例用法
    如果可以的话,你可以embedded JRuby解释器,并通过jruby-ffi调用winapi,这很容易,看到这里 , 在这里 , 这里

我刚才不得不这样做。 你需要一个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的命令,你将不得不调整类/path/等。

 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,这就是我命名我的DL​​L。

在这一点上,你基本上完成了。 正常使用Java类,当您调用静态方法时,它将运行您的Win32代码。 所有你需要做的是导入图书馆。 在你的代码中的某处(我把它放在我的类的一个静态块中),你需要这一行:

 System.loadLibrary("JNIHelper"); 

这将导致Java加载名为“JNIHelper.dll”的库并将其链接到代码中。 它必须位于Java知道的图书馆path的某个地方。

而已。 这是一堆样板,但如果你做一些简单的包装,很容易。 如果你不得不处理Javatypes或分配内存,情况会变得更糟(注意:我没有,所以我没有经验)。

这里有一个完整的教程(首先我今天发现,看起来很不错,你可以在网上find其他人, 维基百科关于JNI的文章也有更多的信息。

希望这可以帮助。

不能直接调用本地库:这是因为Java本地接口不支持方法中的某些参数。

有一个名为GlueGen,这将创build一个独立的二进制文件,将dynamic链接到您的本地DLL。 生成的二进制文件与JNI兼容,因此可以从Java中调用。

http://en.wikipedia.org/wiki/Gluegen

要获取wininet.dll头文件,您可能需要具有平台SDK(或Windows SDK,最新版本)。 你也可以在网上search一个包含这个头文件的在线仓库。

GlueGen将需要一个头文件,一个ANSI C编译器等。

还有一个不太知名的名为NativeCall的库,它不需要GlueGen。 它已经有与Java兼容的二进制文件。 这显然比较慢,因为它会根据Java的请求dynamic加载DLL。 我还没有使用过,但是这听起来很有希望:

http://johannburkard.de/software/nativecall/