从Java调用Win32 API方法

Pau*_*ers 36 java java-native-interface winapi

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

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

我知道这涉及JNI,但我究竟如何做到这一点?我需要javah在Wininet.h 上调用吗?我在哪里可以获得Wininet.h的副本?指向现有详细教程的指针就足够了.

cly*_*yfe 43

  1. JNA似乎是你想要的行业标准,"Java程序提供了对本机共享库(Windows上的DLL)的轻松访问,而无需编写除Java代码之外的任何东西 - 不需要JNI或本机代码"

  2. 也有Java的外交功能接口 - 例如使用
    .如果是对你合适,你可以嵌入JRuby的解释,并通过调用WINAPI JRuby的FFI至极是轻松了很多,看到这里,这里这里

  • 对于这种偶然的原生呼叫,JNA是完美的.但是你不希望将它用于高性能的东西 - 如果你使用WinInet做低级套接字的东西,那么采用真正的JNI实现将是最佳选择. (3认同)
  • 这需要一个突破 - JNA远远优于纯JNI用于本机库访问. (2认同)

MBC*_*ook 14

我不得不在不久前这样做.您需要一个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 */
}
Run Code Online (Sandbox Code Playgroud)

然后使用JDK中的一个命令,它将自动获取您的类并生成.h和.c文件.命令是"javah".方法签名看起来像这样:

JNIEXPORT void JNICALL Java_com_whatever_1thingy_MyClass_callWin32Thingy
    (JNIEnv *, jclass, jint, jint, jboolean);
Run Code Online (Sandbox Code Playgroud)

在.c文件中,您包含所需的任何Windows标头,并充实该方法.

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...
}
Run Code Online (Sandbox Code Playgroud)

这是非常重要的,你不要重命名方法,这就是它被如何与您的特定类关联.

一旦你有了,你将这些文件编译成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
Run Code Online (Sandbox Code Playgroud)

这将产生一些文件,包括JNIHelper.dll,这就是我命名的DLL.

在这一点上,你基本上完成了.您可以正常使用Java类,并在调用静态方法时运行Win32代码.您所要做的就是导入库.你代码中的某个地方(我把它放在我班级的静态块中)你需要这一行:

System.loadLibrary("JNIHelper");
Run Code Online (Sandbox Code Playgroud)

这将导致Java加载名为"JNIHelper.dll"的库并将其链接到代码中.它必须位于Java知道的库路径中的某个位置.

而已.这是一堆样板,但如果你做一些简单的包装,那很简单.如果你必须处理Java类型或分配内存,它会变得更糟(注意:我没有,所以我没有经验).

有一个完整的教程在这里(第一我今天看起来体面的发现,你可以在网络上找到他人.在维基百科上JNI文章有更多的信息了.

希望这可以帮助.