Java 在JNA中是否有一种特殊的方法来处理结构的常量指针成员?

Java 在JNA中是否有一种特殊的方法来处理结构的常量指针成员?,java,struct,mapping,jna,Java,Struct,Mapping,Jna,我有以下C结构: typedef struct { void *instance; const info_st *info; } core_st; 我使用JNA将其映射到以下Java类: public class core_st extends Structure { public Pointer instance; public info_st.ByReference info; @Override protected

我有以下C结构:

typedef struct {
    void           *instance;
    const info_st  *info;
} core_st;
我使用JNA将其映射到以下Java类:

public class core_st extends Structure {

    public Pointer instance;
    public info_st.ByReference info;

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList("instance", "info");
    }
}
以及相对JNA映射:

int open_core(int core_id, core_st[] core);
最后,我编写了一个java程序,以这种方式调用函数:

core_st[] cores = new core_st[1];
MyLibrary.INSTANCE.open_core(0, cores);
函数应使用“打开”操作的结果填充
核心[0]
成员。特别是,这两个字段是指向其他内容的两个指针。发生的情况是,
void*instance
字段始终正确填充,但
info
字段始终为空(指向零的指针)。 如果我将jna.memory\u dump选项设置为true,则对
core\u st.toString()
的任何调用都会返回相同的结果:

memory dump
[70cb64e7]
[fd7f0000]
[00000000]
[00000000]
看起来指向info结构的指针不在JNA读取的内存中。相同的调用由类似的C程序执行,工作正常,两个指针都正确填充。 我还尝试更改核心映射,只是为了测试:

public class core_st extends Structure {

    public long instance;
    public long info;

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList("instance", "info");
    }
}
公共类核心扩展结构{
公共长实例;
公共信息;
@凌驾
受保护列表getFieldOrder(){
返回Arrays.asList(“实例”、“信息”);
}
}
但结果没有什么不同。实例获取一个非null值,并且info始终为null。我正在使用64位虚拟机。 我想知道问题是否可能是info字段的常量修饰符?指针类型的结构字段中的常量修饰符能否更改结构在内存中的存储方式

指针类型的结构字段中的
const
修饰符能否更改结构在内存中的存储方式

答案可能是编译器相关的。您的问题中更重要的是
const
如何影响本机端访问字段的方式。无论您在Java端做什么,一旦您初始化了
核心结构的
info
字段,就不能修改它

这就是为什么你在这里看到了你所看到的:通过定义
public info\u st.ByReference info
您正在使用指向
NULL
的指针初始化
core\st
结构,并获取为该字段存储的内存地址
0x0
。当使用API访问该字段时,不能更改内存地址,它被卡住了

您会看到相同的结果,将其初始化为带有默认值(0)的
long

解决方案取决于API如何填充该值。如果在本机端,
open\u core
函数假定
info
字段已经用指向已分配结构的指针初始化,并且只更改指向内存的值,则所有设置都已设置。您只需要在第一次实例化结构时初始化该字段

你没有告诉我任何关于
*info
指向的内容,因此答案是不同的,这取决于它是
info\u st
结构的数组还是单个结构。如果是单个结构,则您有:

public class core_st extends Structure {

    public Pointer instance;
    public info_st.ByReference info = new info_st.ByReference();

}
这将在此处为
info\u st
结构分配适当的内存,并将只读指针存储在
core\u st
结构中。根据
open_core()
的内部工作原理(根据您的报告,这似乎在C端起作用),这可能会起作用

如果没有,发布工作的C代码可能有助于确定是否有另一个JNA映射会有所帮助,或者您是否必须使用自己的自定义dll包装函数来解决它

指针类型的结构字段中的
const
修饰符能否更改结构在内存中的存储方式

答案可能是编译器相关的。您的问题中更重要的是
const
如何影响本机端访问字段的方式。无论您在Java端做什么,一旦您初始化了
核心结构的
info
字段,就不能修改它

这就是为什么你在这里看到了你所看到的:通过定义
public info\u st.ByReference info
您正在使用指向
NULL
的指针初始化
core\st
结构,并获取为该字段存储的内存地址
0x0
。当使用API访问该字段时,不能更改内存地址,它被卡住了

您会看到相同的结果,将其初始化为带有默认值(0)的
long

解决方案取决于API如何填充该值。如果在本机端,
open\u core
函数假定
info
字段已经用指向已分配结构的指针初始化,并且只更改指向内存的值,则所有设置都已设置。您只需要在第一次实例化结构时初始化该字段

你没有告诉我任何关于
*info
指向的内容,因此答案是不同的,这取决于它是
info\u st
结构的数组还是单个结构。如果是单个结构,则您有:

public class core_st extends Structure {

    public Pointer instance;
    public info_st.ByReference info = new info_st.ByReference();

}
这将在此处为
info\u st
结构分配适当的内存,并将只读指针存储在
core\u st
结构中。根据
open_core()
的内部工作原理(根据您的报告,这似乎在C端起作用),这可能会起作用

如果没有,发布工作的C代码可能有助于确定是否有另一个JNA映射会有所帮助,或者您是否必须使用自己的自定义dll包装函数来解决它