在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返回一个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中实现的代码。