public interface Kernel32 extends StdCallLibrary {
int GetComputerNameW(Memory lpBuffer, IntByReference lpnSize);
}
public class Kernel32Test {
private static final String THIS_PC_NAME = "tiangao-160";
private static Kernel32 kernel32;
@BeforeClass
public static void setUp() {
System.setProperty("jna.encoding", "GBK");
kernel32 = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
}
@AfterClass
public static void tearDown() {
System.setProperty("jna.encoding", null);
}
@Test
public void testGetComputerNameW() {
final Memory lpBuffer = new Memory(1024);
final IntByReference lpnSize = new IntByReference();
final int result = kernel32.GetComputerNameW(lpBuffer, lpnSize);
if (result != 0) {
throw new IllegalStateException(
"calling 'GetComputerNameW(lpBuffer, lpnSize)'failed,errorcode:" + result);
}
final int bufferSize = lpnSize.getValue();
System.out.println("value of 'lpnSize':" + bufferSize);
Assert.assertEquals(THIS_PC_NAME.getBytes().length + 1, bufferSize);
final String name = lpBuffer.getString(0);
System.out.println("value of 'lpBuffer':" + name);
Assert.assertEquals(THIS_PC_NAME, name);
}
}
offical instructions说使用byte [],char [],Memory或NIO Buffer来映射c本机函数中的char指针。但是我尝试了以上所有,并且String,WString,StringArrays,类扩展了PointType等,所有这些都没用。
输出参数'lpnSize'可以返回校正缓冲区大小,但'lpBuffer'返回'x>'(我认为它是随机存储器)或者无论我映射任何java类型都没有。如果我写了一些'lpBuffer'内存首先,它会在调用本机函数后读取相同的内容。
我该如何解决这个问题?
答案 0 :(得分:2)
您需要使用Pointer.getString(0, true)
来提取GetComputerNameW返回的unicode字符串。
修改强>
在函数填充结果之前,您还需要使用已初始化的length参数再次调用GetComputerNameW
。将相同的IntByReference
传回第二次调用,或将IntByReference
初始化为Memory
缓冲区的大小,以便在第一次调用时写入缓冲区。