JNA 中的 RasEnumConnections 函数返回不完整的数据。我做错了什么?

RasEnumConnections function in JNA is returning incomplete data. What I am doing wrong?

在 JNA 中实现的 RasEnumConnections 函数返回不完整的数据。
怎么了?这是我的代码:

public static void main(String[] args) {

    Connected();
}

private static void Connected () {
    boolean state = false;
    ArrayList<String> connectedNames = new ArrayList<>();
    IntByReference lpcb = new IntByReference(0);
    IntByReference lpcConnections = new IntByReference(0);
    Rasapi32.INSTANCE.RasEnumConnections(null, lpcb,lpcConnections);

    WinRas.RASCONN conn = new WinRas.RASCONN();
    conn.dwSize = lpcb.getValue();
    WinRas.RASCONN[] connArray;
    if(lpcConnections.getValue() > 0)
        connArray = (WinRas.RASCONN[])conn.toArray(lpcConnections.getValue());
    else
        connArray = (WinRas.RASCONN[])conn.toArray(1);
    System.out.println("lpcb: " + lpcb.getValue() + " lpcConnections: " + lpcConnections.getValue() + " RASCONN Size: " + conn.dwSize);
    int error = Rasapi32.INSTANCE.RasEnumConnections(connArray, lpcb,lpcConnections);

    if(error == WinError.ERROR_SUCCESS) {
        System.out.println("Entry name: " + Native.toString(connArray[0].szEntryName)
        + " Guid string: " + connArray[0].guidEntry.toGuidString());
        System.out.println(connArray[0].guidEntry.Data1);
        System.out.println(connArray[0].guidEntry.Data2);
        System.out.println(connArray[0].guidEntry.Data3);

    }
    else System.out.println("Error: " + error);

    WinRas.RASENTRY.ByReference entry = getPhoneBookEntry("test1");
    if(entry != null) {
        System.out.println("test1 guid: "+ entry.guidId.toGuidString());
        System.out.println(entry.guidId.Data1);
        System.out.println(entry.guidId.Data2);
        System.out.println(entry.guidId.Data3);
    }

    else System.out.println("Error: " + Native.getLastError());

    }
}

字符数组 szEntryName 仅包含连接名称的最后 3 个字符。 (连接名称是 "test1")

正如我在评论中指出的那样,调试输出强烈提示您正在发生的事情。缺失的 "t" 和 "e" 字符在 JNA 期望的 64 位指针中间显示为 0x74 和 0x65。合乎逻辑的结论是 Windows 是 return 后跟字符串的 32 位指针,比 JNA 预期的早 4 个字节。

RasEnumConnections 说明了一些关于您作为 connArray:

传递的缓冲区的事情

On input, an application must set the dwSize member of the first RASCONN structure in the buffer to sizeof(RASCONN) in order to identify the version of the structure being passed.

在上面的示例代码中,您保留此值与初始 return 中的值相同。这是指定结构的 "wrong" 版本。相反,您应该在 JNA 结构中将 dwSize 成员设置为您想要的大小:

conn.dwSize = conn.size();

实际上,RASCONN sets this for you 的构造函数!所以你实际上不必这样做。但是在上面的代码示例中,您正在覆盖预先设置的内容;只需删除您的 conn.dwSize 行。

请注意,由于您现在通过定义结构大小请求(每个数组元素 4 个字节)更大的缓冲区,因此您还需要在(第二个)RasEnumConnections() 调用中传递增加的大小。它设置为元素数乘以(较小的)结构大小,但您应该重置为元素数乘以(较大的)大小,如下所示:

lpcb.setValue(conn.size() * lpcConnections.getValue());

在获取完整数组之前。否则您将收到错误 632(结构大小不正确)。

为了参考(或者可能是您自己的代码的合适替代品),请查看 getRasConnection(String connName) method in JNA's Rasapi32Util.java class.

中实现的代码