简体   繁体   中英

Is there a specific way to deal with const pointer members of a struct in JNA?

I have the following C structure:

typedef struct {
    void           *instance;
    const info_st  *info;
} core_st;

Which I map to the following Java Class using JNA:

public class core_st extends Structure {

    public Pointer instance;
    public info_st.ByReference info;

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

I also have the following function taken from a dll:

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

And the relative JNA mapping:

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

Finally, I wrote a java program that calls the function this way:

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

The function should populate cores[0] members with the result of the "open" operation. In particular, the two fields are two pointers to something else. What happens is that the void *instance field is always correctly populated, but the info field is always null (a pointer to zero). If I set the jna.memory_dump option to true, any call of core_st.toString() returns always the same result:

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

It looks like the pointer to the info structure is not in the memory read by the JNA. The same call, performed by a similar C program, works fine, both pointers are correctly populated. I also tried to change the core_st mapping, just for test purposes:

public class core_st extends Structure {

    public long instance;
    public long info;

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

But I got no differences in the result. instance gets a non-null value, and info is always null. I am working with a 64bit VM. I was wondering if the problem could be the const modifier of the info field? Can the const modifier in a struct field of type pointer change the way the struct is stored in memory?

Can the const modifier in a struct field of type pointer change the way the struct is stored in memory?

The answer is maybe , compiler dependent. More important to your question is how const affects the way the field is accessed on the native side. No matter what you do on the Java side, once you initialize the info field of your core_st structure, you can not modify it.

And that is why you are seeing what you're seeing here: by defining public info_st.ByReference info; you are initializing the core_st structure with a pointer to NULL and getting the memory address 0x0 stored for that field. When accessing that field using the API, you can't change the memory address, it's stuck.

You see the same results initializing it as a long with the default value (0).

The solution depends on how the API populates that value. If, on the native side, the open_core function assumes that the info field is already initialized with a pointer to an allocated structure, and just changes the values at the pointed-to memory, you're all set. You just need to initialize that field when you first instantiate the structure.

You don't tell me anything about what *info points to, so the answer is different depending on whether it's an array of info_st structures or a single structure. If it's a single structure, you have:

public class core_st extends Structure {

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

}

This will allocate the appropriate memory here for an info_st structure and store the read-only pointer in your core_st structure. Depending on the inner workings of open_core() (and based on your report that this seems to work on the C side), this may work!

If not, perhaps posting the working C code would help determine whether there's another JNA mapping that would help or if you have to work around it with your own custom dll wrapper function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM