当前位置: 首页 > 面试题库 >

如何使GetLastError可靠地与JNA一起使用?

简宏义
2023-03-14
问题内容

我在Java应用程序中使用各种Win32 API函数,并GetLastError用来获取有关失败的API调用的信息。

在大多数情况下,它都可以工作,但是现在我发现了一种情况,似乎有些东西可以重置最后一个错误。

这是我在Java应用程序和VB6应用程序中所做的事情:

  1. 我用PID 4(系统)打开处理过程的句柄
  2. 我打GetModuleFileNameEx那个电话。
  3. 我打GetProcessImageFileName那个电话。

现在, 两个
API函数均按预期失败(它们返回零),并且在我的VB6应用程序中GetLastError,两个API调用之后均返回87(“无效参数”)。

但是在我的Java应用程序中,仅在GetModuleFileNameEx将最后一个错误设置为87之后。之后GetProcessImageFileName它始终为零。

我该怎么办?

编辑:

以下是JNA声明:

public interface PsApi extends StdCallLibrary {
    PsApi INSTANCE = (PsApi) Native.loadLibrary("psapi", PsApi.class, 
            W32APIOptions.UNICODE_OPTIONS);
    int GetModuleFileNameEx(WinNT.HANDLE hProcess, WinDef.HMODULE hModule, 
            char[] lpFilename, int nSize);
    int GetProcessImageFileName(WinNT.HANDLE hProcess, char[] lpImageFileName, 
            int nSize);
}

和调用代码 GetProcessImageFileName

char[] buffer = new char[2048];
int result = PsApi.INSTANCE.GetProcessImageFileName(hProcess, buffer, 
   buffer.length);
if (result == 0) {
    throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
return new String(Arrays.copyOf(buffer, result));

而对于 GetModuleFileNameEx

char[] buffer = new char[2048];
int result = PsApi.INSTANCE.GetModuleFileNameEx(hProcess, hModule, buffer,
    buffer.length);
if (result == 0) {
     throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
return new String(Arrays.copyOf(buffer, result));

问题答案:

该文档描述了两个选项:

如果函数设置了系统错误属性(errno或GetLastError()),则在JNA映射中声明异常时,错误代码将作为LastErrorException抛出。或者,您可以使用Native.getLastError()进行检索,前提是已使用一个真值调用了Native.setPreserveLastError(boolean)。最好抛出一个异常,因为它具有更好的性能。

调用的问题GetLastError是JNA框架以及Java运行时实际上可能调用Windows函数来重置错误。因此,您不应尝试GetLastError直接致电。



 类似资料:
  • 问题内容: 我正在设置信用卡处理程序,需要对CURL使用替代方法。当我使用测试服务器(未调用SSL URL)时,以下代码运行良好,但是现在当我在使用HTTPS的工作服务器上对其进行测试时,它失败,并显示错误消息“无法打开流”。 问题答案: 请尝试以下脚本,以查看您的php脚本是否有https包装器。 输出应该是这样的

  • Redux framework正在使用reducers来更改应用程序状态以响应操作。 关键要求是缩减器不能修改现有的状态对象;它必须产生一个新的对象。 错误示例: 好例子: 这是一个很好的Immutable.js.用例

  • 如何强制testcontainers使用本地映像?

  • 问题内容: 我将使用IntelliJ Community Edition的Git版本控制来创建我打算开发的程序的分支。我正在努力使自己适应其功能,并且遇到了障碍。 我遵循网页 http://wiki.jetbrains.net/intellij/Using_Git_Locally上的说明,尽管我按其要求进行操作,但是当我到达Image5时,在Default(默认)下找到了一个空列表。 我认为这可能

  • 作为参考,我们有两个选项可以让Multipart与Spring Security一起工作: 在Spring Security之前放置MultipartFilter 在行动中包括CSRF令牌 对于第一种选择,我尝试了以下方法: 创建安全应用程序初始化类: > 在application.properties中更改Spring安全过滤器顺序 然后添加FilterRegistrationBean 不幸的是