从 Java 调用 Win32 API 方法

2022-09-01 05:58:55

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

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

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


答案 1
  1. JNA似乎是你想要的行业标准,“让Java程序能够轻松访问本机共享库(Windows上的DLL),除了Java代码之外什么都不写 - 不需要JNI或本机代码”

  2. 还有Java外函数接口 - 示例用法
    如果适合您,您可以嵌入JRuby解释器并通过jruby-ffi调用winapi,这要容易得多,请参阅此处此处此处


答案 2

不久前我不得不这样做。您将需要一个 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类型或分配内存,情况会变得更糟(注意:我没有,所以我没有这方面的经验)。

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

希望这有帮助。


推荐