0

I'm consuming a C library in Java with GraalVm and I have this field (if_name) I don't know how to implement:

# define IFNAMSIZ 16

struct port_t
{
   char if_name[IFNAMSIZ]; 
}

This is my current code:

@CStruct("port_t")
interface Port extends PointerBase {
    
    @CField("if_name")
    WordPointer getIfName();

    @CField("if_name")
    void setIfName(WordPointer ifName);
}

Using WordPointer I get the following error compiling:

Error: Type WordPointer has a size of 8 bytes, but accessed C value has a size of 16 bytes; to suppress this error, use the annotation @AllowNarrowingCast

I already tried with CCharPointer and CCharPointerPointer but those have fixed lengths to 8 bytes and I got a similar error when compiling.

Anyone can help? Thanks in advance

Ikaro
  • 165
  • 1
  • 12

1 Answers1

1

As you already guessed, you'll need to get the address of this field to manipulate it. You can use

@CStruct("port_t")
interface Port extends PointerBase {
    @CFieldAddress("if_name")
    CCharPointer addressOfIfName();
}

In this case it doesn't make sense to have a setter since you cannot change the address of this field. Instead you can use the read/write methods of CCharPointer.

You'll probably need

@CConstant
static native int IFNAMSIZ();

somewhere as well. Then you can do things like

String foo(Port p, String newIfName) {
    UnsignedWord size = WordFactory.unsigned(IFNAMSIZ());
    String oldIfName = CTypeConversion.toJavaString(p.addressOfIfName(), size);
    CTypeConversion.toCString(newIfName, p.addressOfIfName(), size);
    return oldIfName;
}
Gilles D.
  • 1,167
  • 6
  • 16
  • Thanks, @Gilles D. That worked perfectly! If you have time could you take a look at this one? Maybe it rings the bell for you: https://stackoverflow.com/questions/71569963/how-to-declare-extern-field-with-graalvm-nativeimage – Ikaro Apr 20 '22 at 07:58