【问题标题】:call method from existing external .dll. For ex, CopyFileA from kernel32.dll从现有的外部 .dll 调用方法。例如,来自 kernel32.dll 的 CopyFileA
【发布时间】:2025-12-05 02:45:01
【问题描述】:

任务是从现有的 dll 中调用方法。 我正在尝试对 kernel32.dll 中的 CopyFileA 示例执行此操作。

方法签名是:

Function long CopyFileA(String lpExistingFileName, String lpNewFileName, boolean bFailifExists) Library "kernel32"

这就是我在 java 中尝试这样做的方式:

public class Test {

    static {
        System.loadLibrary("D:\\test\\kernel32");
    }

    public static void main(String[] args) {
        (new Test()).CopyFileA("D:\\test\\hi.txt", "D:\\other\\hi.txt", false);
    }

    public native long CopyFileA(String lpExistingFileName, String lpNewFileName, boolean bFailifExists);
}

我明白了:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Test.CopyFileA(Ljava/lang/String;Ljava/lang/String;Z)J

我找到的所有手册都描述了您编写 C 代码然后为自己创建 dll 的示例。因此,您可以使用生成的头文件中的签名来实现本机方法。 但是这里我们已经有了一个 dll。

谢谢!

【问题讨论】:

    标签: java dll java-native-interface native


    【解决方案1】:

    您所看到的示例是最好的方法。需要完成一些控制代码以使 Java 能够调用本机方法,反之亦然。如果没有这个线束代码,它们中的任何一个都无法相互通信。

    如果您迫切需要调用 CopyFileA,则在一些 C/C++ 代码中创建工具代码,然后调用 CopyFileA。

    如果您试图避免使用 C/C++ 编程,那么您的 java 就无法与 CopyFileA 进行通信。

    可能有第三方代码可以帮助您。我不知道。

    【讨论】:

      【解决方案2】:

      这非常简单:您只需下载jna.jar 文件并将其包含到您的项目中即可。
      下面我放了一些代码 sn-p 如何解决您的任务:

      Function showWindow = Function.getFunction("kernel32", "CopyFileA");
      Object[] params = new Object[3];
      params[0] = "D:\\test\\hi.txt";
      params[1] = "D:\\other\\hi.txt";
      params[2] = false;
      Object result = showWindow.invoke(params);
      

      【讨论】: