当前位置: 首页 > 知识库问答 >
问题:

有没有一种特定的方法来处理 JNA 中结构的 const 指针成员?

卢权
2023-03-14

我有如下的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");
    }
}

我还有以下从dll中获取的函数:

uint32_t open_core(uint32_t core_id, core_st **core);

以及相对的JNA映射:

int open_core(int core_id, core_st[] core);

最后,我编写了一个java程序,以这种方式调用函数:

core_st[] cores = new core_st[1];
MyLibrary.INSTANCE.open_core(0, cores);

该函数应该用“打开”操作的结果填充cores[0]成员。特别是,这两个字段是指向其他东西的两个指针。发生的情况是,void*实例字段总是正确填充,但info字段总是null(指向零的指针)。如果我将jna.memory_dump选项设置为true,任何调用core_st.toString()总是返回相同的结果:

memory dump
[70cb64e7]
[fd7f0000]
[00000000]
[00000000]

看起来info结构的指针不在JNA读取的内存中。由类似的C程序执行的同一个调用工作正常,两个指针都被正确填充。我还试图更改core_st映射,只是为了测试:

public class core_st extends Structure {

    public long instance;
    public long info;

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList("instance", "info");
    }
}

但是我在结果上没有任何不同。实例获得非空值,而info始终为空。我正在使用64位虚拟机。我想知道这个问题是否可能是信息字段的常量修饰符?指针类型的结构字段中的const修饰符可以改变结构在内存中的存储方式吗?

共有1个答案

衡修洁
2023-03-14

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

答案可能取决于编译器。对于您的问题,更重要的是const如何影响本地端访问字段的方式。无论您在Java端做什么,一旦初始化core_st结构的信息字段,就不能修改它。

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

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

解决方案取决于API如何填充该值。如果在本机端,open_core函数假定信息字段已经用指向已分配结构的指针初始化,并且只更改指向内存的值,则一切就绪。您只需要在首次实例化结构时初始化该字段。

你没有告诉我任何关于< code>*info指向什么的信息,所以答案是不同的,取决于它是< code>info_st结构的数组还是单个结构。如果是一个单一的结构,你有:

public class core_st extends Structure {

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

}

这将在此处为info_st结构分配适当的内存,并将只读指针存储在core_st结构中。根据open_core()的内部工作原理(并且基于您的报告,这似乎适用于C端),这可能有效!

如果没有,也许发布工作的C代码将有助于确定是否有其他JNA映射会有所帮助,或者您是否必须使用自己的自定义dll包装函数来解决这个问题。

 类似资料:
  • 问题内容: 我的孩子做了一项家庭作业,用Java编写二十一点。我为他提供了一些帮助,但大部分时间他都是自己完成的,实际上效果还不错。他甚至发现了我在计算手值时没有看到的错误。但是,他还没有解决一个难题,我能想到的每个解决方案都非常复杂,而且远远超出了他将能够利用其仍基本的Java技能轻松编写代码的范围。 王牌。实际上,不仅有一个Ace,还有四个Ace,您可能可以一手拿到所有四个Ace。当有一个或多

  • 第三方DLL有一个函数,该函数需要一个指向结构的指针作为参数: 它将手指指纹(通常为4个)的“拍打”图像分割成单独的指纹(手指的文件名)。 SrapInfo的定义是: C中的示例片段: 根据JNA常见问题解答,在我的情况下,我应该使用“结构”: 所以,我用Java/JNA做了这样的映射: 但是使用这种方法,我得到了错误: 我还尝试了: < li >指针引用而不是SlapInfo。ByReferen

  • 我需要向用户显示以下座位并能够预订和取消预订。 我也尝试了unordered_map,但无论我做什么,我都无法使map以我想要的方式显示座位(1A,1B,1C,1D,1E)。 1A 1B 1C 1D 1E 2A 2B 2C 2D 2E... 尝试将座位名称更改为A1 B1 C1 D1...显然,我是C++新手。我知道地图是有序的,并且我知道使用unordered_map无法保证地图的显示方式。 我

  • 我试着在Firebase Analytics中吸引观众,将“app version”设置为“contains‘debug’”。我的应用程序的调试版本在版本名字符串的末尾追加“-debug”。 但是,当我运行应用程序时,虽然Firebase为我的会话记录数据,但它没有为“调试观众”记录任何数据。 是否有一种方法来创建开发人员构建的受众,不管是通过版本名,还是任何其他方法? 谢谢!

  • 在我的应用程序中,有几个组件将生成各种不同类型的特定于应用程序的事件。这些事件将发布到代理并传递给N个客户端。其中一些客户端是我的服务器端应用程序中的其他Java类,但主要消费者是我的基于javascript的WebUI。 到目前为止,我目前的方法是定义一个抽象事件基类来封装一些公共字段,然后为每个事件实现一个特定的事件类。 这一直工作正常,只是现在我需要在javascript和java端维护事件

  • 我有五个属性的列表,每个属性有五个不同的值。我想生成它们的笛卡尔乘积,并过滤所有独特的排列。 一些背景: 我需要它们作为我的输入值来解决逻辑难题。在那里我对照他们检查规则以找到正确的解决方案。 也许一个简化的例子就能说清楚。 数据: 数据的笛卡尔乘积: 我想要的是: 我不想要的是: 我不希望同一个值多次出现。位置很重要,因此它应该具有置换性质,对于包含五个元素的列表,它应该具有置换性质。我猜输出大