![](/img/trans.png)
[英]How do I pass a Structure that contains an array of Structures to a C++ function using JNA?
[英]How to pass an array of structures using JNA
我引用了另一篇stackoverflow文章“如何将指针映射到JNA中的结构数组”以提出以下代码来枚举Windows服务依赖项。
结构和功能声明:
static class SERVICE_STATUS extends Structure {
public int dwServiceType;
public int dwCurrentState;
public int dwControlsAccepted;
public int dwWin32ExitCode;
public int dwServiceSpecificExitCode;
public int dwCheckPoint;
public int dwWaitHint;
public SERVICE_STATUS(){}
}
static class ENUM_SERVICE_STATUS extends Structure {
public ENUM_SERVICE_STATUS(){ }
public WString lpServiceName;
public WString lpDisplayName;
SERVICE_STATUS serviceStatus;
}
boolean EnumDependentServicesW(Pointer hService, int serviceState, ENUM_SERVICE_STATUS serviceStatuses, int size, IntByReference bytesNeeded, IntByReference servicesReturned);
如果只有一个服务依赖项,则以下代码有效:
IntByReference bytesNeeded = new IntByReference();
IntByReference numberOfServices = new IntByReference();
Advapi32.ENUM_SERVICE_STATUS serviceStatus = new Advapi32.ENUM_SERVICE_STATUS();
Advapi32.ENUM_SERVICE_STATUS[] serviceStatuses = (Advapi32.ENUM_SERVICE_STATUS[]) serviceStatus.toArray(1);
if (!advapi32.EnumDependentServicesW(serviceHandle, Advapi32.SERVICE_ACTIVE, null, 0, bytesNeeded, numberOfServices)) {
if (advapi32.EnumDependentServicesW (serviceHandle, Advapi32.SERVICE_ACTIVE, serviceStatuses[0], bytesNeeded.getValue(), bytesNeeded, numberOfServices)) {
for(int i = numberOfServices.getValue() - 1; i >= 0; i--){
logger.debug("Service Name: " + serviceStatuses[i].lpServiceName.toString());
}
}
如果有2个服务依赖项,则在logger.debug调用中获得lpServiceName的NullPointerException:
IntByReference bytesNeeded = new IntByReference();
IntByReference numberOfServices = new IntByReference();
Advapi32.ENUM_SERVICE_STATUS serviceStatus = new Advapi32.ENUM_SERVICE_STATUS();
Advapi32.ENUM_SERVICE_STATUS[] serviceStatuses = (Advapi32.ENUM_SERVICE_STATUS[]) serviceStatus.toArray(2);
if (!advapi32.EnumDependentServicesW(serviceHandle, Advapi32.SERVICE_ACTIVE, null, 0, bytesNeeded, numberOfServices)) {
if (advapi32.EnumDependentServicesW (serviceHandle, Advapi32.SERVICE_ACTIVE, serviceStatuses[0], bytesNeeded.getValue(), bytesNeeded, numberOfServices)) {
for(int i = numberOfServices.getValue() - 1; i >= 0; i--){
logger.debug("Service Name: " + serviceStatuses[i].lpServiceName.toString());
}
}
上面的代码的numberOfServices值为2,如预期的那样。 我试图传递结构数组而不是指针,因为我希望JNA进行内存同步。 我应该如何传递/使用结构数组?
根据EnumDependentServices
的文档 ,
lpServices [输出,可选]
指向ENUM_SERVICE_STATUS结构数组的指针,该数组接收数据库中每个相关服务的名称和服务状态信息。 缓冲区必须足够大以容纳结构以及它们的成员指向的字符串。
您几乎忽略了bytesNeeded
报告的所需缓冲区大小。 您应该使用bytesNeeded
值创建所需大小的Memory
实例,然后使用该Memory
实例创建新的ENUM_SERVICE_STATUS
实例,而不是独立于所需的缓冲区大小来创建结构。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.