JNA传递对字节数组的引用无法正常工作

问题描述

我的本​​机代码是:

int xlSetApplConfig(
char *appName,unsigned int appChannel,unsigned int hwType,unsigned int hwIndex,unsigned int hwChannel,unsigned int busType)

我试图用Java中的Pointer来表达appName

    //integers..
    byte[] appnamebyte = new String("JEdit").getBytes();
    Pointer appname = new Memory(appnamebyte.length);
    appname.write(0,appnamebyte,appnamebyte.length);
    int status = dll.INSTANCE.xlOpenPort(portHandle,appname,channelMask,permissionMask,rxQueueSize,xlInterfaceVersion,busType);

函数正在将字节数组写入注册表或某个位置,并且可以使用其他工具(给定一个)读取该值。 如果我启动代码,则没有错误,但是appname并非始终正确。有时会有比我想要的字符更多的字符(“ JEdit?78ê”)。 也许以某种方式分配了比我想要的更多的内存。 我也尝试传递一个普通的byte [],但是有同样的问题

解决方法

您遇到的问题是C字符串必须以null终止。简单地从String抓取字节就只能得到字符J,E,d,i和t。您的数组需要有一个第六字节(值为0)才能正常工作。

执行此操作的一种方法是保留您拥有的Pointer映射并自己分配额外的字节,然后使用Pointer.setString()将字节写入该本地内存:

Memory buffer = new Memory(6);
// make sure the last byte is 0
memory.clear(); // could also just set the last byte
buffer.setString(0,"JEdit");

(请注意,这依赖于默认平台编码,通常这是一个坏主意。您应该指定编码;在这种情况下,US-ASCII应该可以使用。

您也可以像以前一样保留setString(),并使用以0结尾的write()参数。

或者,如果要在函数中使用数组映射而不是byte[],则只需声明一个新数组:

Pointer

或者,使用上面的命令并像现在一样写入终止的// initializes all elements to 0 byte[] appnameNullTerminated = new byte[appname.length+1]; System.arraycopy(appname,appnameNullTerminated,appname.length); 数组。

同样,请确保您控制字符到字节的编码。使用byte[]而不指定编码通常是一个坏主意。