0

Below is the code I am working with: C API:

typedef struct {
    int matId;
    int nMatNameSize;
    char* materialName;
    int isHyMat;
    lDVDetailOutput* dVOutputs;
} innerStruct;

typedef struct {
    int nMaterials;
    innerStruct** moreDetailOutputs;
} detailOutput;

int LDValues(const char* version,
             const detailInput* input,
             detailOutput* output);

JNA Declarations:

public static class lDVDetailOutput extends Structure {
    public static class ByReference extends lDVDetailOutput implements Structure.ByReference{}

    int dValue;
    int nVars;
    yetAnotherStructure.ByReference vars;

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList(new String[] { 
            "dValue", "nVars", "yetAnotherStructure", });
    }
}

public static class jInnerStruct extends Structure{
    int matId;
    int nMatNameSize;
    String materialName;
    int isHyMat;
    lDVDetailOutput.ByReference dValueOutputs;

    jInnerStruct() {
        super();
    }

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList(new String[] { 
            "matId", "nMatNameSize", "materialName",
            "isHyMat", "dValueOutputs", });
    }
}

public static class jDetailOutput extends Structure {
    public static class ByReference extends detailOutput implements Structure.ByReference{}

    int nMaterials;
    Pointer moreDetailOutputs; // jInnerStruct**

    public jDetailOutput(Pointer p) {
        super(p);
        read();
    }

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList(new String[] { 
            "nMaterials", "moreDetailOutputs", });
    }
}

public static LDValues(final String inputString,
                       final jDetailInput.ByReference inputValues,
                       jDetailOutput.ByReference outputValues) {}

In my main program I have the following code:

jDetailOutput.ByReference recvDetailOutput = new jDetailOutput.ByReference();

int success = LDValues(stringObject, inputValues, recvDetailOutput);

Pointer[] myDetailOutputPointers = recvDetailOutput.moreDetailOutputs.getPointerArray(0, recvDetailOutput.detailOutput.nMaterials);

jInnerStruct interimLMDO = new jInnerStruct(matDetailOutputPointers[0]);

I am getting a Memory Access error during the read() call in the jDetailOutput(Pointer P) constructor. Specifically when trying to read the dValueOutputs member of jInnerStruct.

Using the Eclipse debugger I see that dValueOutputs has a value of null. I do see that nMaterials in jDetailOutput has a correct value in it.

Do I need to create a different constructor for jInnerStruct?

Thanks, Doug

  • Is any further documentation provided for `LDValues` or the structs? Do you have a working prototype written in C? – cbr Jan 30 '18 at 16:00
  • Also remember to provide an implementation for [`getFieldOrder`](http://java-native-access.github.io/jna/4.5.0/javadoc/com/sun/jna/Structure.html#getFieldOrder--). – cbr Jan 30 '18 at 16:04
  • I have implemented the getFieldOrder already. – Douglas Lewis Jan 30 '18 at 20:36
  • I do not have a working prototype in C at this time. What are you looking for as further documentation? – Douglas Lewis Jan 30 '18 at 20:38
  • Be sure to the `getFieldOrder`-implementing version in your answer. The documentation would tell whether it expects any structs' members to point to pre-allocated memory and whether they're just pointers or actually arrays etc. – cbr Jan 30 '18 at 20:48
  • I've added the getFieldOrder function to the Structures. I also noticed that the declaration of LDValues was incorrect so I corrected that, added ".ByReference". @cubrr – Douglas Lewis Jan 31 '18 at 13:56
  • Let me see what I can provide as far as documentation: `moreDetailOutputs` is expected to be an array containing pointers to `jInnerStruct`. – Douglas Lewis Jan 31 '18 at 14:03
  • The basic field type is `Pointer`, then you use `Pointer.getPointer(0)` to get the first `struct*`. You can use this pointer to initialize a Java-side `Structure`. `Pointer.getPointerArray(0, len)` may be used to get a full array of the saved pointers. JNA can often do the translation automatically (see the [FAQ](https://github.com/java-native-access/jna/blob/master/www/FrequentlyAskedQuestions.md#when-should-i-use-structurebyreference-structurebyvalue-structure) for hints on how to handle different variations). – technomage Jan 31 '18 at 18:00

0 Answers0