jna toarray()重置结构字段?

6bc51xsx  于 2021-07-11  发布在  Java
关注(0)|答案(1)|浏览(429)

考虑以下jna结构:

public class VkDeviceQueueCreateInfo extends VulkanStructure {
    public VkStructureType sType = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
    public Pointer pNext;
    public int flags;
    public int queueFamilyIndex;
    public int queueCount;
    public Pointer pQueuePriorities;
}

这个 sType 字段是本机层用于标识结构类型的常量值。对于使用 new .
但是,如果我们使用 toArray() 这个 sType 在为每个数组元素调用构造函数后重置为默认值。i、 它清理了场地!
无效的替代方案:
在构造函数中显式设置字段没有效果(它仍然会被重置)。
同样的道理 final .
不管我们是尝试默认构造函数还是使用jna的构造函数,似乎都无关紧要 Pointer 争论。
唯一有效的方法是关闭结构的自动读取:

public class VkDeviceQueueCreateInfo extends VulkanStructure {
    ...
    public VkDeviceQueueCreateInfo() {
        setAutoRead(false);
    }
}

(请注意,此结构仅用于写入本机层,而不用于读回任何内容)。
这是可行的,但它到底在做什么呢?为什么jna要将结构重置为本机值,而现在还没有呢?有没有办法全局关闭此字段的自动读取?
对于单个结构来说,这不是什么大事,但是在这个项目中,有几百个是从本机层生成的代码,其中大多数(但不是全部)是用 sType 如上例所示预填充。显然,预先填充这个领域并不是一条路要走,但还有什么选择呢?每个结构都需要用上面的小提琴重新生成吗?
编辑:在思考这个问题之后,我想到的另一个相关问题是:结构中的数组类型是什么?它们是否重置为 null 自动阅读工具?代码生成的结构初始化任何数组以调整结构的大小,例如。 public float[] colour = new float[4];

prdp8dxp

prdp8dxp1#

你在正确的轨道上指出汽车- read() 是问题的一部分。当你调用 toArray() 您(通常)将阵列的内存备份更改为新的本机内存分配(自动分配会将内存归零)。所以所有这些0都被加载到你的数组中。
内部结构 toArray() 为方便起见,保留第一个元素的值,但对其余元素不做任何操作,其余元素使用 newInstance() 在回路内部。以下是导致问题的两条线:

array[i] = newInstance(getClass(), memory.share(i*size, size));
array[i].conditionalAutoRead();

我的建议是你推翻 toArray() 你自己的 VulkanStructure 其他人继承的结构。您可以复制现有代码,并根据需要进行修改(例如,删除自动读取)。
或者你可以超负荷工作 toArray() 在将旧集合读入新集合之前,通过备份内存传递一组结构和副本。或者,如果原始内存备份足够大 toArray() 调用时,内存不会被清除。所以你可以分配你自己足够大的内存,使用 useMemory() 在第一个元素上改变其备份,并在备份内存上复制字节;它们将被自动读入新的数组版本。

相关问题