我的目标是使用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);
}
MainClass.java:
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)
这是EnumProcesses的语法:
BOOL WINAPI EnumProcesses(
_Out_ DWORD *pProcessIds,
_In_ DWORD cb,
_Out_ DWORD *pBytesReturned
);
如果PSAPI_VERSION为2或更大,则此函数在Psapi.h中定义为K32EnumProcesses,并在Kernel32.lib和Kernel32.dll中导出。如果PSAPI_VERSION为1,则此函数在Psapi.h中定义为EnumProcesses,并在Psapi.lib和Psapi.dll中作为调用K32EnumProcesses的包装程序导出。资料来源:msnd.microsoft.com
我尝试使用K32EnumProcesses和EnumProcesses。结果相同。
最佳答案
为Windows创建一个64位的动态链接库
先决条件:Visual Studio
1 /创建一个Visual Studio C ++项目(例如:dllexample)
•选择“ Win32 Consol应用程序”
选择“ DLL”
选择“空项目”
2 /在“解决方案资源管理器”中,右键单击“头文件”>“添加”>“新建项…”>选择一个名称(例如:dllexample.h)>“添加”
•通过以下方式在“ dllexample.h”中定义函数的标题:
__declspec(dllexport) <type> funcName(parameters…);
…
3 /在“解决方案资源管理器”中,右键单击“源文件”>“添加”>“新建项…”>选择一个名称(例如:dllexample.cpp)>“添加”
• 采用:
#include “dllexample.h”
•在“ dllexample.cpp”源文件中定义函数的主体(来自“ dllexample.h”头文件):
<type> funcName(parameters…){
//body instructions
}
•在上方工具栏中,选择“ x64”
•选择“构建”>“构建解决方案”
4 /完成
•您可以在“ projects / dllexample / x64 / Debug”中找到“ dllexample.dll”和“ dllexample.lib”
•您可以在“ projects / dllexample / dllexample”中找到“ dllexample.h”
从Windows上的另一个64位DLL或可执行文件调用64位DLL文件(例如:dllexample.dll)
先决条件:“ dllexample.dll”,“ dllexample.lib”和“ dllexample.h”或精确的功能描述或指南以及Visual Studio
1 /创建一个Visual Studio C ++项目(例如:dllcall)
•选择“ Win32 Consol应用程序”
选择“ DLL”创建一个DLL文件,选择“ Consol Application”创建一个可执行文件
选择“空项目”
2 /将“ dllexample.dll”,“ dllexample.lib”和“ dllexample.h”复制到“ projects / dllcall / dllcall”
3 /在“解决方案资源管理器”中,右键单击“头文件”>“添加”>“现有项…”>选择“ dllexample.h”>“添加”
•如果要制作DLL文件,请创建一个新的头文件(例如:dllcall.h),在其中您可以通过以下方式定义函数的头:
__declspec(dllexport) <type> funcName(parameters…);
…
4 /在“解决方案资源管理器”中,右键单击“源文件”>“添加”>“新建项…”>选择一个名称(例如:dllcall.cpp)>“添加”
• 采用:
#include “dllexample.h”
•如果要创建DLL文件,请使用:
#include “dllcall.h”
然后在“ dllcall.cpp”源文件中定义函数的主体(来自“ dllcall.h”头文件)。同时,您可以从“ dllexample.h”调用函数:
<type> funcName(parameters…){
//body instructions
}
•在上方工具栏中,选择“ x64”
•在“解决方案资源管理器”中,右键单击“ dllcall”>“属性”>“链接器”>“输入”>“其他依赖项”>“编辑”>添加“ dllexample.lib”(此选项仅针对当前Visual Studio项目的x64调试器)
•选择“构建”>“构建解决方案”以生成DLL和导入库(.lib)文件,选择“运行”以生成可执行文件并对其进行测试
5 /完成
•您可以在“ projects / dllcall / x64 / Debug”中找到“ dllcall.dll”和“ dllcall.lib”或“ dllcall.exe”
•您可以在“ projects / dllcall / dllcall”中找到“ dllcall.h”
通过JNI从64位Java程序调用64位DLL文件(例如:dllexample.dll)
先决条件:“ dllexample.dll”,“ dllexample.lib”和“ dllexample.h”或精确的功能描述或指南。 Visual Studio,带有JNI插件的Eclipse
1 /创建一个Eclipse Java项目(例如:dlltest)
2 /创建一个类(例如:my.package.JNIClass)
•使用关键字在“ dllexample.h”中的函数定义附近定义方法标头:
public static final native <type> funcName(parameters..);
…
•运行项目以生成“ JNIClass.class”
3 /在“ workspace / dllcall / src”文件夹中打开命令行
•通过运行以下命令生成“ my_package_JNIClass.h”头文件:
javah my.package.JNIClass
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中的“ Solution Explorer”,然后右键单击“ Properties”>“ Configuration Properties”>“ C / C ++”>“常规”>“其他包含目录”>添加64位“ java / include”和“ java / include / win32”路径(此选项仅为当前Visual Studio项目的x64调试器设置)
5 /将“ dllcall.dll”和“ dllexample.dll”复制到“ workspace / dllcall / src”
•在“ Package Explorer”中,右键单击“ dlltest”>“ Properties”>“ Java Build Path”>“ Source”>展开“ my / package / src”>选择“ Native Library Location”>“ Edit”>添加“ my / package / src”作为位置路径
•使用以下命令将DLL文件导入“ JNIClass.java”中:
static {
System.loadLibrary(“dllexample”);
System.loadLibrary(“dllcall”);
}
6 /如果未选择64位JRE,则转到“运行”>“运行配置”>“ JRE”>“备用JRE”>“已安装JRE”>放入64位Java JDK目录(应该是这样的: “ C:\ Program Files \ Java \ jdk”,而在“ Program Files(x86)”文件夹中可以找到32位Java JDK
7 /完成
•现在,您可以使用在步骤2中定义的方法
关于java - 使用JNI调用给定DLL文件中定义的函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44926904/