简体   繁体   English

如何使用JNA传递结构数组

[英]How to pass an array of structures using JNA

I referenced another stackoverflow article "How do I map a pointer to an array of structures in JNA" to come up with the following code to enumerate Windows service dependencies. 我引用了另一篇stackoverflow文章“如何将指针映射到JNA中的结构数组”以提出以下代码来枚举Windows服务依赖项。

Structure and function declarations: 结构和功能声明:

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);

If there is only one service dependency, the following code works: 如果只有一个服务依赖项,则以下代码有效:

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());
    }
}

If there are 2 service dependencies, I get a NullPointerException for lpServiceName in the logger.debug call: 如果有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());
    }
}

The numberOfServices value for the code above is 2, as expected. 上面的代码的numberOfServices值为2,如预期的那样。 I'm trying to pass the structure array instead of a pointer because I want JNA to do the memory synching. 我试图传递结构数组而不是指针,因为我希望JNA进行内存同步。 How should I be passing/using the array of structures? 我应该如何传递/使用结构数组?

According to the docs for EnumDependentServices , 根据EnumDependentServices文档

lpServices [out, optional] lpServices [输出,可选]

A pointer to an array of ENUM_SERVICE_STATUS structures that receives the name and service status information for each dependent service in the database. 指向ENUM_SERVICE_STATUS结构数组的指针,该数组接收数据库中每个相关服务的名称和服务状态信息。 The buffer must be large enough to hold the structures, plus the strings to which their members point. 缓冲区必须足够大以容纳结构以及它们的成员指向的字符串。

You're pretty much ignoring the required buffer size as reported by bytesNeeded . 您几乎忽略了bytesNeeded报告的所需缓冲区大小。 You should use the bytesNeeded value to create a Memory instance of the requisite size, then use that Memory instance to create a new ENUM_SERVICE_STATUS instance, instead of creating the structure independently of the required buffer size. 您应该使用bytesNeeded值创建所需大小的Memory实例,然后使用该Memory实例创建新的ENUM_SERVICE_STATUS实例,而不是独立于所需的缓冲区大小来创建结构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM