我的目标是使用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。相同的结果。
答案 0 :(得分:0)
先决条件:Visual Studio
1 /创建Visual Studio C ++项目(例如:dllexample)
•选择“Win32 Consol Application”
2 /在“解决方案资源管理器”中右键单击“头文件”> “添加”> “New Item ...”>选择一个名字(例如:dllexample.h)> “添加”
•以这种方式在“dllexample.h”中定义函数的标题:
__declspec(dllexport) <type> funcName(parameters…);
…
3 /在“解决方案资源管理器”中右键单击“源文件”&gt; “添加”&gt; “New Item ...”&gt;选择一个名字(例如:dllexample.cpp)&gt; “添加”
•使用:
#include “dllexample.h”
•在“dllexample.cpp”源文件中定义函数体(来自“dllexample.h”头文件):
<type> funcName(parameters…){
//body instructions
}
•在上方工具栏中选择“x64”
•选择“构建”&gt; “构建解决方案”
4 /完成
•您可以在“projects / dllexample / x64 / Debug”中找到“dllexample.dll”和“dllexample.lib”
•您可以在“projects / dllexample / dllexample”中找到“dllexample.h”
先决条件:“dllexample.dll”,“dllexample.lib”和“dllexample.h”或精确的函数说明或指南以及Visual Studio
1 /创建Visual Studio C ++项目(例如:dllcall)
•选择“Win32 Consol Application”
2 /将“dllexample.dll”,“dllexample.lib”和“dllexample.h”复制到“projects / dllcall / dllcall”
3 /在“解决方案资源管理器”中右键单击“头文件”&gt; “添加”&gt; “现有项目......”&gt;选择“dllexample.h”&gt; “添加”
•如果您正在制作DLL文件,请创建一个新的头文件(例如:dllcall.h),您可以通过这种方式定义函数的标题:
__declspec(dllexport) <type> funcName(parameters…);
…
4 /在“解决方案资源管理器”中右键单击“源文件”&gt; “添加”&gt; “New Item ...”&gt;选择一个名字(例如:dllcall.cpp)&gt; “添加”
•使用:
#include “dllexample.h”
•如果您要创建DLL文件,请使用:
#include “dllcall.h”
然后在“dllcall.cpp”源文件中定义函数体(来自“dllcall.h”头文件)。同时,您可以从“dllexample.h”调用函数:
<type> funcName(parameters…){
//body instructions
}
•在上方工具栏中选择“x64”
•在“解决方案资源管理器”中,右键单击“dllcall”&gt; “属性”&gt; “链接器”&gt; “输入”&gt; “附加依赖性”&gt; “编辑”&gt;添加“dllexample.lib”(此选项仅为当前Visual Studio项目的x64调试器设置)
•选择“构建”&gt; “Build Solution”生成DLL和导入库(.lib)文件,“Run”生成可执行文件并测试它
5 /完成
•您可以在“projects / dllcall / x64 / Debug”中找到“dllcall.dll”和“dllcall.lib”或“dllcall.exe”
•您可以在“projects / dllcall / dllcall”中找到“dllcall.h”
先决条件:“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”&gt; “配置属性”&gt; “C / C ++”&gt; “一般”&gt; “其他包含目录”&gt;添加64位“java / include”和“java / include / win32”路径(此选项仅为当前Visual Studio项目的x64调试器设置)
5 /将“dllcall.dll”和“dllexample.dll”复制到“workspace / dllcall / src”
•在“Package explorer”中,右键单击“dlltest”&gt; “属性”&gt; “Java构建路径”&gt; “来源”&gt;展开“my / package / src”&gt;选择“本机库位置”&gt; “编辑”&gt;将“my / package / src”添加为位置路径
•使用以下命令在“JNIClass.java”中导入DLL文件:
static {
System.loadLibrary(“dllexample”);
System.loadLibrary(“dllcall”);
}
6 /如果未选择64位JRE,则转到“运行”&gt; “运行配置”&gt; “JRE”&gt; “替代JRE”&gt; “已安装的JRE”&gt;把64位Java JDK目录(应该是这样的:“C:\ Program Files \ Java \ jdk”,而32位Java JDK可以在“Program Files(x86)”文件夹中找到
7 /完成
•现在您可以使用在步骤2中定义的方法