我使用 JNA 从 java 调用 ac 函数。该函数将字符串列表写入用户提供的内存,其签名如下:
void c_getStrings(char *buf, size_t bufSize, char *strings[], size_t *stringsCount)
使用 Java 版本:
public interface TestCaseDLL extends Library
{
int c_getStrings(byte[] buf, int bufSize, Memory strings, IntByReference stringCount);
}
public class TestCase
{
public static void main(String[] args)
{
byte[] buf = new byte[100];
Memory strings = new Memory(Memory.SIZE * 10);
IntByReference stringCount = new IntByReference(10);
// c_getStrings() will write the strings continuously to 'buf' and
// additionally return a list of starting addresses through the
// 'strings' parameter (that is 'strings' point into 'buf').
// 'stringCount' holds the initial array size of 'strings' and will
// return the count of returned strings.
TestCaseDLL.INSTANCE.c_getStrings(buf, buf.length, strings, stringCount);
System.out.println(strings.getPointer(0).getString(0));
System.out.printf("%c\n", buf[0]); // how can this line change 'strings'?
System.out.println(strings.getPointer(0).getString(0));
for (byte b: buf) {
System.out.print((char) b);
}
System.out.println("");
for (byte b: buf) {
System.out.printf("%#x ", b);
}
System.out.println("");
}
}
输出
??llo world!
H
?
Hello world! Hallo Welt! Ciao a tutti!
0x48 0x65 0x6c 0x6c 0x6f 0x20 0x77 0x6f 0x72 0x6c 0x64 0x21 0x0 0x48 0x61 0x6c 0x6c 0x6f 0x20 0x57 0x65 0x6c 0x74 0x21 0x0 0x43 0x69 0x61 0x6f 0x20 0x61 0x20 0x74 0x75 0x74 0x74 0x69 0x21 0x0 ...
我遇到了以下问题:
- 返回的字符串已损坏。它应该返回“Hello World!” 而不是“??llo world!”
- 打印
buf[0]
会更改返回的字符串。我现在知道这里发生了什么,因为我只是在阅读它的价值。
我的类型映射是否损坏或者我缺少一些基本的东西?
更新
我现在使用使用
void c_getStrings(Memory buf, int bufSize, String[] strings, IntByReference stringCount);
如果我要重做它,我会按照 technomage 的建议将它分成两个功能:
void c_fill(char *buf, size_t bufSize);
void c_parseToStringArray(const char *buf, const char *strings[], size_t stringsSize);