JNA:如何访问结构体中的结构体数组?

发布于 2024-10-02 04:59:41 字数 4003 浏览 3 评论 0原文

我正在尝试访问结构内的结构数组。这是相关的 C 代码,简化为问题:

typedef struct {
  int a;
  int b;
} fileinfo_t;

typedef struct {
  fileinfo_t **file;
  int max_files;
} project_t;

在 C 中访问数组就像这样简单:

int var_a_of_file_0 = project.file[0].a;
int var_b_of_file_1 = project.file[1].b;

如何在 Java 中实现它?我问这个问题是因为我是 JNA 的新手。到目前为止,我阅读了 JNA 文档并尝试了与我的问题以某种方式相关的每个示例,但没有运气......

我使用 JNAerator 来转换头文件。我不确定结果是否正确:

package test;
import com.ochafik.lang.jnaerator.runtime.LibraryExtractor;
import com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper;
import com.ochafik.lang.jnaerator.runtime.Structure;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.ptr.PointerByReference;
/**
 * JNA Wrapper for library <b>test</b><br>
 * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
 * a tool written by <a href="http://ochafik.free.fr/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
 * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
 */
public interface TestLibrary extends Library {
    public static final java.lang.String JNA_LIBRARY_NAME = LibraryExtractor.getLibraryPath("test", true, test.TestLibrary.class);
    public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(test.TestLibrary.JNA_LIBRARY_NAME, com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper.DEFAULT_OPTIONS);
    public static final TestLibrary INSTANCE = (TestLibrary)Native.loadLibrary(test.TestLibrary.JNA_LIBRARY_NAME, test.TestLibrary.class, com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper.DEFAULT_OPTIONS);
    public static class fileinfo_t extends Structure<fileinfo_t, fileinfo_t.ByValue, fileinfo_t.ByReference > {
        public int a;
        public int b;
        public fileinfo_t() {
            super();
        }
        public fileinfo_t(int a, int b) {
            super();
            this.a = a;
            this.b = b;
        }
        protected ByReference newByReference() { return new ByReference(); }
        protected ByValue newByValue() { return new ByValue(); }
        protected fileinfo_t newInstance() { return new fileinfo_t(); }
        public static fileinfo_t[] newArray(int arrayLength) {
            return Structure.newArray(fileinfo_t.class, arrayLength);
        }
        public static class ByReference extends fileinfo_t implements Structure.ByReference {

        };
        public static class ByValue extends fileinfo_t implements Structure.ByValue {

        };
    };
    public static class project_t extends Structure<project_t, project_t.ByValue, project_t.ByReference > {
        /// C type : fileinfo_t**
        public PointerByReference file;
        public int max_files;
        public project_t() {
            super();
        }
        /// @param file C type : fileinfo_t**
        public project_t(PointerByReference file, int max_files) {
            super();
            this.file = file;
            this.max_files = max_files;
        }
        protected ByReference newByReference() { return new ByReference(); }
        protected ByValue newByValue() { return new ByValue(); }
        protected project_t newInstance() { return new project_t(); }
        public static project_t[] newArray(int arrayLength) {
            return Structure.newArray(project_t.class, arrayLength);
        }
        public static class ByReference extends project_t implements Structure.ByReference {

        };
        public static class ByValue extends project_t implements Structure.ByValue {

        };
    };
}

任何帮助将不胜感激。

I'm trying to access an array of struct inside a struct. This is the relevant C code reduced to the problem:

typedef struct {
  int a;
  int b;
} fileinfo_t;

typedef struct {
  fileinfo_t **file;
  int max_files;
} project_t;

In C accessing the array is as easy as this:

int var_a_of_file_0 = project.file[0].a;
int var_b_of_file_1 = project.file[1].b;

How do I implement this in Java? I'm asking this question because I'm new to JNA. So far I read the JNA documentation and tried every example which is somehow related to my problem but with no luck...

I used JNAerator for converting the header file. I don't know for shure if the result is correct:

package test;
import com.ochafik.lang.jnaerator.runtime.LibraryExtractor;
import com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper;
import com.ochafik.lang.jnaerator.runtime.Structure;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.ptr.PointerByReference;
/**
 * JNA Wrapper for library <b>test</b><br>
 * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
 * a tool written by <a href="http://ochafik.free.fr/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
 * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
 */
public interface TestLibrary extends Library {
    public static final java.lang.String JNA_LIBRARY_NAME = LibraryExtractor.getLibraryPath("test", true, test.TestLibrary.class);
    public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(test.TestLibrary.JNA_LIBRARY_NAME, com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper.DEFAULT_OPTIONS);
    public static final TestLibrary INSTANCE = (TestLibrary)Native.loadLibrary(test.TestLibrary.JNA_LIBRARY_NAME, test.TestLibrary.class, com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper.DEFAULT_OPTIONS);
    public static class fileinfo_t extends Structure<fileinfo_t, fileinfo_t.ByValue, fileinfo_t.ByReference > {
        public int a;
        public int b;
        public fileinfo_t() {
            super();
        }
        public fileinfo_t(int a, int b) {
            super();
            this.a = a;
            this.b = b;
        }
        protected ByReference newByReference() { return new ByReference(); }
        protected ByValue newByValue() { return new ByValue(); }
        protected fileinfo_t newInstance() { return new fileinfo_t(); }
        public static fileinfo_t[] newArray(int arrayLength) {
            return Structure.newArray(fileinfo_t.class, arrayLength);
        }
        public static class ByReference extends fileinfo_t implements Structure.ByReference {

        };
        public static class ByValue extends fileinfo_t implements Structure.ByValue {

        };
    };
    public static class project_t extends Structure<project_t, project_t.ByValue, project_t.ByReference > {
        /// C type : fileinfo_t**
        public PointerByReference file;
        public int max_files;
        public project_t() {
            super();
        }
        /// @param file C type : fileinfo_t**
        public project_t(PointerByReference file, int max_files) {
            super();
            this.file = file;
            this.max_files = max_files;
        }
        protected ByReference newByReference() { return new ByReference(); }
        protected ByValue newByValue() { return new ByValue(); }
        protected project_t newInstance() { return new project_t(); }
        public static project_t[] newArray(int arrayLength) {
            return Structure.newArray(project_t.class, arrayLength);
        }
        public static class ByReference extends project_t implements Structure.ByReference {

        };
        public static class ByValue extends project_t implements Structure.ByValue {

        };
    };
}

Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏花。依旧 2024-10-09 04:59:41

由于结构数组不会覆盖包含结构的内存,因此您需要该字段的指针或等效类型。然后,您可以从基指针手动派生所需的结构。

但是,我认为您的使用示例无效。

一旦你用“[0]”索引,你就有了一个指向 fileinfo_t 的指针,所以你必须使用以下内容(你实际上用 C 编译了你的示例吗?):

int var_a_of_file_0 = project.file[0]->a;
int var_b_of_file_1 = project.file[1]->b;

最终如何提取实际结构取决于它们的放置方式在内存中,这在您当前的解释中是不明确的。

Since the array of structs does not overlay the containing struct's memory, you need a Pointer or equivalent type for that field. You can then manually derive the structure you need from the base pointer.

I don't think your usage example is valid, however.

Once you index with "[0]", you have a pointer to fileinfo_t, so you would have to use the following (have you actually compiled your example in C?):

int var_a_of_file_0 = project.file[0]->a;
int var_b_of_file_1 = project.file[1]->b;

Ultimately how you extract the actual structures depends on how they are laid out in memory, which is ambiguous in your current explanation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文