java - JNA toArray() 重置结构字段?
问题描述
考虑以下 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
.
但是,如果我们在为每个数组元素调用构造函数后,使用 is分配此结构的数组toArray()
,则将sType
其重置为默认值。即它清除了领域!
无效的替代方案:
- 在构造函数中显式设置字段没有效果(它仍然会被重置)。
- 同上
final
。 - 我们是否尝试使用默认构造函数或带有 JNA
Pointer
参数的构造函数似乎并不重要。
唯一可行的方法是关闭结构的自动读取:
public class VkDeviceQueueCreateInfo extends VulkanStructure {
...
public VkDeviceQueueCreateInfo() {
setAutoRead(false);
}
}
(请注意,此结构仅用于写入本机层,不回读任何内容)。
这行得通,但它实际上在做什么?为什么 JNA 将结构重置为本机值时还没有?有没有办法在全局范围内关闭该字段的自动读取?
这对于单个结构来说不是什么大问题,但是在这个项目中,有数百个是从原生层生成的代码,其中大部分(但不是全部)都sType
像上面的示例一样预先填充。显然,预先填充该字段不是要走的路,但有什么替代方案?是否需要使用上述小提琴重新生成每个结构?
编辑:深思熟虑后想到的另一个相关问题 - 结构中的数组类型呢?它们是否null
被自动读取的东西重置?代码生成的结构初始化任何数组以调整结构的大小,例如public float[] colour = new float[4];
解决方案
您在正确的轨道上指出自动read()
是这里问题的一部分。当您调用时,toArray()
您(通常)将数组的内存支持更改为新的本机内存分配(自动分配将内存清零)。所以所有这些 0 都被加载到你的数组中。
为了方便起见,内部结构toArray()
保留了第一个元素的值,但对其余元素不做任何事情,这些元素newInstance()
在循环内使用实例化。这是导致您的问题的两行:
array[i] = newInstance(getClass(), memory.share(i*size, size));
array[i].conditionalAutoRead();
我的建议是让您toArray()
在自己的VulkanStructure
结构中覆盖其他人继承的结构。您可以复制现有代码并根据需要对其进行修改(例如,删除自动读取)。
或者,您可以重载一个toArray()
传递结构集合的 a,并在将旧集合读取到新集合之前将其复制到支持内存上。toArray()
或者,如果调用时原始内存支持足够大,则不会清除内存。因此,您可以分配自己的足够大的内存,useMemory()
在第一个元素上使用以更改其支持,并复制支持的内存字节;并且它们将被自动读入新的数组版本。
推荐阅读
- r - 如何从数百个 .csv 文件中的特定单元格中提取值?
- python - 如何读取 Google 通讯录 csv 文件?
- mysql - 如何将2个表与多列进行比较
- c# - 系统测试 - 如何在不实际保存数据的情况下测试数据库
- asp.net - 将 WebMethod 的序列化程序从 JsonDataContractSerializer 更改为 NewtonSoft Json Serializer
- apache-spark - 无法使用 where 子句过滤镶木地板文件....错误“不安全符号不稳定”
- java - 根据特定条件使用 Spring Boot 从 MongoDb 检索数据
- javascript - 多个显示和隐藏按钮
- php - 如何在php中计算和显示数组值
- css - 更改大纲文本字段的默认边框颜色