考虑以下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];
1条答案
按热度按时间prdp8dxp1#
你在正确的轨道上指出汽车-
read()
是问题的一部分。当你调用toArray()
您(通常)将阵列的内存备份更改为新的本机内存分配(自动分配会将内存归零)。所以所有这些0都被加载到你的数组中。内部结构
toArray()
为方便起见,保留第一个元素的值,但对其余元素不做任何操作,其余元素使用newInstance()
在回路内部。以下是导致问题的两条线:我的建议是你推翻
toArray()
你自己的VulkanStructure
其他人继承的结构。您可以复制现有代码,并根据需要进行修改(例如,删除自动读取)。或者你可以超负荷工作
toArray()
在将旧集合读入新集合之前,通过备份内存传递一组结构和副本。或者,如果原始内存备份足够大toArray()
调用时,内存不会被清除。所以你可以分配你自己足够大的内存,使用useMemory()
在第一个元素上改变其备份,并在备份内存上复制字节;它们将被自动读入新的数组版本。