I would like the conversion done by JNA to be automatic. Right now I am following the solution from the second answer in a very similar question and the JNA own EnumConverter utility class. There is one important difference, my listing has a constructor argument.
My code defining TypeConverter:
public class SentinelStatusConverter implements TypeConverter {
@Override
public SentinelStatus fromNative(Object nativeValue, FromNativeContext context) {
Integer code = (Integer) nativeValue;
return SentinelStatus.fromCode(code);
}
@Override
public Integer toNative(Object value, ToNativeContext context) {
SentinelStatus status = (SentinelStatus) value;
return Integer.valueOf(status.getCode());
}
@Override
public Class<Integer> nativeType() {
return Integer.class;
}
}
public class SentinelTypeMapper extends DefaultTypeMapper {
public SentinelTypeMapper() {
addTypeConverter(SentinelStatus.class, new SentinelStatusConverter());
}
}
Here the code directly registers its own C library along with my custom one TypeMapper. The C functions return intwhich I want to automatically map to an enumeration SentinelStatus:
public class SentinelLibrary {
static {
Map<String, Object> options = new HashMap<String, Object>();
options.put(Library.OPTION_TYPE_MAPPER, new SentinelTypeMapper());
Native.register(NativeLibrary.getInstance("libnamelib", options));
}
public static native SentinelStatus hasp_get_sessioninfo(
NativeLong sessionHandle,
String query,
PointerByReference info);
}
SentinelStatusis enumas follows:
public enum SentinelStatus {
HASP_STATUS_OK(0),
HASP_SOME_ERROR(13),
...
HASP_NOT_IMPL(1831);
private final int code;
SentinelStatus(final int code) { this.code = code; }
public int getCode() { return this.code; }
public static SentinelStatus fromCode(final int code) {
for (SentinelStatus status : EnumSet.allOf(SentinelStatus.class)) {
if (code == status.getCode()) {
return status;
}
}
return SentinelStatus.HASP_NOT_IMPL;
}
}
JNA- , SentinelLibrary:
java.lang.ExceptionInInitializerError
...
Caused by: java.lang.IllegalArgumentException: Unsupported Structure field type class package.name.SentinelStatus
at com.sun.jna.Structure$FFIType.get(Structure.java:1851)
at com.sun.jna.Structure$FFIType.get(Structure.java:1806)
at com.sun.jna.Native.register(Native.java:1438)
at com.sun.jna.Native.register(Native.java:1165)
at package.name.SentinelLibrary.<clinit>(line with Native.register() call)
. NativeMapped , .
C ?
UPDATE:
JNA SentinelStatus enum:
public final static TypeMapper TYPE_MAPPER = new SentinelTypeMapper();
SentinelLibrary . , , null , stderr:
JNA: unrecognized return type, size 4