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

问题描述 投票:1回答:1

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

    }
}

In debugger:

字符串数组szEntryName仅包含3个连接名称的最后一个字符。 (连接名称为“test1”)

java jna
1个回答
0
投票

正如我在评论中所指出的那样,调试输出会为您提供强有力的提示。丢失的“t”和“e”字符在JNA期望为64位指针的中间显示为0x74和0x65。逻辑结论是Windows返回一个32位指针,后跟字符串,比JNA预期的早4个字节。

RasEnumConnections陈述了关于你作为connArray传递的缓冲区的一些事情:

在输入时,应用程序必须将缓冲区中第一个RASCONN结构的dwSize成员设置为sizeof(RASCONN),以便标识要传递的结构的版本。

在上面的示例代码中,您将保留此值与初始返回的值相同。这是指定结构的“错误”版本。相反,您应该将dwSize成员设置为JNA结构中所需的大小:

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中实现的代码。

© www.soinside.com 2019 - 2024. All rights reserved.