问题描述
我的本机代码是:
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[]
而不指定编码通常是一个坏主意。