我是靠谱客的博主 飞快丝袜,最近开发中收集的这篇文章主要介绍jna 构造函数_如何使用TypeConverter通过JNA将C整数映射到Java枚举?,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

我想自动进行JNA的转换.现在我正在遵循第二个答案

in a very similar question和JNA自己的

EnumConverter实用程序类的解决方案.有一个关键的区别,我的枚举有一个构造函数参数.

我定义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 nativeType() {

return Integer.class;

}

}

public class SentinelTypeMapper extends DefaultTypeMapper {

public SentinelTypeMapper() {

addTypeConverter(SentinelStatus.class, new SentinelStatusConverter());

}

}

这里的代码直接注册本机C库以及我的自定义TypeMapper. C函数返回一个int,我想自动映射到SentinelStatus枚举:

public class SentinelLibrary {

static {

Map options = new HashMap();

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);

}

SentinelStatus是这样的枚举:

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.(line with Native.register() call)

我已经阅读了文档,对映射的类或类型没有任何限制.只有NativeMapped接口需要实现者提供公共无参数构造函数.

是否可以通过这种方式将C整数映射到枚举?

更新:

在通过JNA代码进一步搜索后,我已将此字段添加到SentinelStatus枚举中:

public final static TypeMapper TYPE_MAPPER = new SentinelTypeMapper();

现在SentinelLibrary加载没有错误.但是所有返回枚举的方法都返回null,并将错误打印到stderr:

JNA: unrecognized return type, size 4

最佳答案 您最有可能在库定义的上下文之外定义结构(这是存储TypeMapper信息的位置).

您可以在Structure类上显式设置类型映射器,也可以在本机库类中定义Structure类.如果没有为Structure明确定义TypeMapper,它将回退到任何周围的Library类提供的选项.

public class MyStructure extends Structure {

public MyStructure() {

setTypeMapper(new MyTypeMapper());

}

}

或者,

public interface MyLibrary extends Library {

public class MyStructure extends Structure {

}

}

或者直接映射:

public class MyLibrary implements Library {

{ Native.register(...); }

public class MyStructure extends Structure { }

}

当Structure类无法找到显式设置的类型映射器时,它会查找类型为Library的封闭类,并尝试查找实例化该类时使用的选项.加载本机库时会缓存这些选项,因此可以使用库子类作为键通过键查找获得这些选项.您需要实现Library接口,以便将直接映射库识别为本机库类.

编辑

这是JNA的类型映射器处理中的错误(参见project issue).这似乎仅限于直接映射库和枚举类型映射.

编辑

这里有几个JNA错误,如果您想尝试它,可以使用fix is available.此问题与直接映射库上的映射器类型隔离,其中原语正在转换为Java对象.

最后

以上就是飞快丝袜为你收集整理的jna 构造函数_如何使用TypeConverter通过JNA将C整数映射到Java枚举?的全部内容,希望文章能够帮你解决jna 构造函数_如何使用TypeConverter通过JNA将C整数映射到Java枚举?所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(33)

评论列表共有 0 条评论

立即
投稿
返回
顶部