Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JNI调用给定DLL文件中定义的函数_Java_Eclipse_Visual Studio_Dll_Java Native Interface - Fatal编程技术网

Java 使用JNI调用给定DLL文件中定义的函数

Java 使用JNI调用给定DLL文件中定义的函数,java,eclipse,visual-studio,dll,java-native-interface,Java,Eclipse,Visual Studio,Dll,Java Native Interface,我的目标是使用JNI从kernel32.dll访问函数。正如你在下面看到的,我做得很糟糕。我在答案中写下了整个过程 Kernel32.java: package tn.kernel; public final class Kernel32 { public static boolean loadKernel32(){ System.loadLibrary("kernel32"); return true; } public static

我的目标是使用JNI从kernel32.dll访问函数。正如你在下面看到的,我做得很糟糕。我在答案中写下了整个过程

Kernel32.java

package tn.kernel;

public final class Kernel32 {
    public static boolean loadKernel32(){
        System.loadLibrary("kernel32");
        return true;
    }

    public static native boolean K32EnumProcesses(int[] pProcessIds, int cb, int[] pBytesReturned);
}
package tn.kernel;

public class MainClass {

    public static void main(String[] args) {
        System.out.println("Program started.");

        if(Kernel32.loadKernel32())
            System.out.println("Kernel32.dll loaded.");

        int n = 2000;
        int[] procs = new int[n];
        int ls = Integer.SIZE;
        int[] rs = new int[1];

        if(Kernel32.K32EnumProcesses(procs, ls * n, rs)){
            System.out.println("Success");
        }

        System.out.println("Done.");
    }

}
MainClass.java

package tn.kernel;

public final class Kernel32 {
    public static boolean loadKernel32(){
        System.loadLibrary("kernel32");
        return true;
    }

    public static native boolean K32EnumProcesses(int[] pProcessIds, int cb, int[] pBytesReturned);
}
package tn.kernel;

public class MainClass {

    public static void main(String[] args) {
        System.out.println("Program started.");

        if(Kernel32.loadKernel32())
            System.out.println("Kernel32.dll loaded.");

        int n = 2000;
        int[] procs = new int[n];
        int ls = Integer.SIZE;
        int[] rs = new int[1];

        if(Kernel32.K32EnumProcesses(procs, ls * n, rs)){
            System.out.println("Success");
        }

        System.out.println("Done.");
    }

}
输出:

Program started.
Kernel32.dll loaded.
Exception in thread "main" java.lang.UnsatisfiedLinkError: tn.kernel.Kernel32.K32EnumProcesses([II[I)Z
    at tn.kernel.Kernel32.K32EnumProcesses(Native Method)
    at tn.kernel.MainClass.main(MainClass.java:15)
以下是枚举进程的语法:

BOOL WINAPI EnumProcesses(
  _Out_ DWORD *pProcessIds,
  _In_  DWORD cb,
  _Out_ DWORD *pBytesReturned
);
如果PSAPI_版本为2或更高,则此函数在PSAPI.h中定义为K32EnumProcesses,并在Kernel32.lib和Kernel32.dll中导出。如果PSAPI_VERSION为1,则此函数在PSAPI.h中定义为EnumProcesses,并在PSAPI.lib和PSAPI.dll中导出为调用K32EnumProcesses的包装器。来源:msnd.microsoft.com

我尝试了K32EnumProcess和EnumProcess。相同的结果。

为Windows创建64位动态链接库 先决条件:Visual Studio

1创建VisualStudioC++项目(EX:DLLIVE)

•选择“Win32控制台应用程序”

  • 选择“DLL”
  • 选择“空项目”
2/在“解决方案资源管理器”中,右键单击“头文件”>“添加”>“新项目…”>选择名称(例如:dllexample.h)>“添加”

•通过以下方式在“dllexample.h”中定义函数的标题:

__declspec(dllexport) <type> funcName(parameters…);
…
__declspec(dllexport) <type> funcName(parameters…);
…
•在“dllexample.cpp”源文件中定义函数体(从“dllexample.h”头文件):

<type> funcName(parameters…){
    //body instructions
}
•如果要创建DLL文件,请使用:

#include “dllcall.h”
然后在“dllcall.cpp”源文件中定义函数体(来自“dllcall.h”头文件)。同时,您可以从“dllexample.h”调用函数:

<type> funcName(parameters…){
    //body instructions
}
4/创建一个64位DLL文件(例如:dllcall.DLL),该文件调用“dllexample.DLL”,并包含“my_package_JNIClass.h”

•在“dllcall.cpp”源文件中,定义在“my_package_JNIClass.h”头文件中定义的函数体

•“my_package_JNIClass.h”包括“jni.h”,要使其正常工作,必须转到Visual Studio中的“解决方案资源管理器”,右键单击“属性”>“配置属性”>“C/C++”>“常规”>“其他包含目录”>添加64位“java/Include”和“java/Include/win32”路径(此选项将仅为当前Visual Studio项目的x64调试器设置)

5/将“dllcall.dll”和“dllexample.dll”复制到“workspace/dllcall/src”

•在“包资源管理器”中,右键单击“dlltest”>“属性”>“Java构建路径”>“源”>展开“my/Package/src”>选择“本机库位置”>“编辑”>添加“my/Package/src”作为位置路径

•使用以下方法导入“JNIClass.java”中的DLL文件:

static {
    System.loadLibrary(“dllexample”);
    System.loadLibrary(“dllcall”);
}
6/如果未选择64位JRE,则转到“运行”>“运行配置”>“JRE”>“备用JRE”>“已安装JRE”>放置64位Java JDK目录(应该类似于:“C:\Program Files\Java\JDK”,而32位Java JDK可以在“Program Files(x86)”文件夹中找到

7/完成

•现在,您可以使用步骤2中定义的方法为Windows创建64位动态链接库 先决条件:Visual Studio

1创建VisualStudioC++项目(EX:DLLIVE)

•选择“Win32控制台应用程序”

  • 选择“DLL”
  • 选择“空项目”
2/在“解决方案资源管理器”中,右键单击“头文件”>“添加”>“新项目…”>选择名称(例如:dllexample.h)>“添加”

•通过以下方式在“dllexample.h”中定义函数的标题:

__declspec(dllexport) <type> funcName(parameters…);
…
__declspec(dllexport) <type> funcName(parameters…);
…
•在“dllexample.cpp”源文件中定义函数体(从“dllexample.h”头文件):

<type> funcName(parameters…){
    //body instructions
}
•如果要创建DLL文件,请使用:

#include “dllcall.h”
然后在“dllcall.cpp”源文件中定义函数体(来自“dllcall.h”头文件)。同时,您可以从“dllexample.h”调用函数:

<type> funcName(parameters…){
    //body instructions
}
4/创建一个64位DLL文件(例如:dllcall.DLL),该文件调用“dllexample.DLL”,并包含“my_package_JNIClass.h”

•在“dllcall.cpp”源文件中,定义在“my_package_JNIClass.h”头文件中定义的函数体

•“my_package_JNIClass.h”包括“jni.h”,要使其正常工作,必须转到Visual Studio中的“解决方案资源管理器”,右键单击“属性”>“配置属性”>“C/C++”>“常规”>“其他包含目录”>添加64位“java/Include”和“java/Include/win32”路径(此选项将仅为当前Visual Studio项目的x64调试器设置)

5/将“dllcall.dll”和“dllexample.dll”复制到“workspace/dllcall/src”

•在“包资源管理器”中,右键单击“dlltest”>“属性”>“Java构建路径”>“源”>展开“my/Package/src”>选择“本机库位置”>“编辑”>添加“my/Package/src”作为位置路径

•使用以下方法导入“JNIClass.java”中的DLL文件:

static {
    System.loadLibrary(“dllexample”);
    System.loadLibrary(“dllcall”);
}
6/如果未选择64位JRE,则转到“运行”>“运行配置”>“JRE”>“备用JRE”>“已安装JRE”>放置64位Java JDK目录(应该类似于:“C:\Program Files\Java\JDK”,而32位Java JDK可以在“Program Files(x86)”文件夹中找到

7/完成


•现在您可以使用步骤2中定义的方法了

您是否让loadKernel32返回true?@efekActive是的,它确实返回true。您可以看到它写着“Kernel32.dll loaded”在输出中是的。对不起。您是否厌倦了在详细模式下运行jvm以查看是否有任何有意义的消息?这不是
native
的工作方式;请参阅javah工具。使用JNI,您定义了应用程序所需的服务,并编写了一个DLL