我有一个 native C 结构,其中包含一个指向字符串的指针:
struct mystruct {
char *name;
}
以及一个为名称分配内存的 native 函数:
void fill(struct mystruct *s, int count) {
for (int i = 0; i < count; i++)
s[i].name = strdup("something");
}
对应的Java结构和native方法是
class MyStruct extends Structure {
String name;
}
和void fill(MyStruct[] structs, int count)
用于填充一些实例。然后我会像这样使用它:
MyStruct[] structs = new MyStruct[10];
fill(structs, structs.length);
完成后,有一个必须调用的清理例程void free(MyStruct[] structs)
,它清理整个数组(strdup分配的所有内存) 。没有办法对结构体实例方法进行清理。
我面临的问题是释放数组后,Java 字符串已损坏。如何为每个 MyStruct 实例创建一个副本,以便释放 native 内存,并只处理使用纯 Java 字符串的 MyStruct 实例?
最佳答案
一旦释放了支持struct
的 native 内存,您就不应该再引用该Java对象,或者您应该创建一个具有自己的内存支持的新对象。
如果您需要手动管理内存,请勿将字段映射到String
,而是使用Pointer
,例如
class MyStruct extends Structure {
public Pointer name;
public String getName() { return name == null ? null : name.getString(0); }
}
一般来说,在释放 native 内存支持后,使用 JNA Structure
不会直接伤害,只要您不调用 Structure.read()
或 Structure.write()
(请注意,JNA 在 native 函数调用之前和之后自动调用这些方法)。但是,如果您选择这样做,请确保您知道自己在做什么;有更安全的方法来开发代码。
关于java - JNA:释放 native 内存后存储 Java String 的副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18344711/