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

官方说明说使用byte[]、char[]、Memory 或 NIO Buffer 来映射 c 本机函数中的 char 指针。但是我尝试了以上所有方法,以及 String、WString、StringArrays、class extends PointType 等,都没有采用。

输出参数'lpnSize'可以返回正确的缓冲区大小,但是'lpBuffer'返回'x>'(我认为是随机内存)或者不管我映射任何java类型都没有。如果我先写一些东西到'lpBuffer'内存,调用本机函数后它会读取相同的内容。

我该如何解决这个问题?

4

1 回答 1

2

您需要用于Pointer.getString(0, true)提取GetComputerNameW返回的 unicode 字符串。

编辑

在函数填充结果之前,您还需要GetComputerNameW使用初始化的长度参数再次调用。要么将相同的内容传回IntByReference给第二次调用,要么将 初始化为缓冲区IntByReference的大小,Memory以便在第一次调用中写入缓冲区。

于 2013-06-27T11:35:20.690 回答