JNA: Как получить доступ к массиву структуры в структуре? - PullRequest
0 голосов
/ 14 ноября 2010

Я пытаюсь получить доступ к массиву структуры внутри структуры. Это соответствующий код 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 {

        };
    };
}

Любая помощь будет оценена.

1 Ответ

0 голосов
/ 25 июля 2011

Поскольку массив структур не перекрывает память содержащейся структуры, вам необходим указатель или эквивалентный тип для этого поля. Затем вы можете вручную извлечь необходимую структуру из базового указателя.

Я не думаю, что ваш пример использования действителен.

Как только вы индексируете с помощью «[0]», у вас есть указатель на fileinfo_t, поэтому вам придется использовать следующее (вы действительно скомпилировали свой пример в C?):

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

В конечном счете, как вы извлекаете фактические структуры, зависит от того, как они расположены в памяти, что неоднозначно в вашем текущем объяснении.

...