如何在JNA中映射枚举

我有以下枚举如何在jna中映射?

该枚举在结构中进一步引用。

typedef enum { eFtUsbDeviceNotShared, eFtUsbDeviceSharedActive, eFtUsbDeviceSharedNotActive, eFtUsbDeviceSharedNotPlugged, eFtUsbDeviceSharedProblem } eFtUsbDeviceStatus; 

阿卜杜勒·哈利克

如果您正在使用JNA,则可能需要在Java中显式指定枚举的值。 默认情况下,Java的基本枚举类型并不能真正为您提供该function,您必须为EnumSet添加构造函数(请参阅此内容和此内容 )。

编码C枚举的一种简单方法是使用包含在与枚举同名的类中的public static final const int。 您可以从Java枚举中获得大部分function,但分配值的开销略微减少。

下面提供了一些很好的JNA示例,包括下面的代码段(已复制)。

假设你的C代码如下:

 enum Values { First, Second, Last }; 

然后Java看起来像:

 public static interface Values { public static final int First = 0; public static final int Second = 1; public static final int Last = 2; } 

在我的博客上,我写了一个方便的方法来使用真正的 Java enum和JNA ,而不仅仅是任意的int 。 它有点复杂,但它有几个优点:

  • 您可以获得大多数类型安全和错误预防
  • 您的IDE可以建议/自动完成任务
  • 您可以创建更多类更简单的Java API

基本上,您需要为enum使用自定义TypeConverter ,并通过简单的TypeMapper提供给JNA。 大多数额外代码是为了避免需要为每个不同的enum类创建单独的TypeConverter 。 (就我而言,我不得不做很多。)


你可以在我的jhllib项目中看到一些真实的代码。 特别是,请查看HlTypeMapper , EnumConverter和JnaEnum的定义和用法。

在结构中引用此枚举时,您只想将其声明为int,而不是eFtUsbDeviceStatus或类似的东西。 作为示例,请参阅下面的AcOnLineWake:

 import com.sun.jna.Native; import com.sun.jna.Structure; import com.sun.jna.win32.StdCallLibrary; public class JNAPlayground { public interface PowrProf extends StdCallLibrary { PowrProf INSTANCE = (PowrProf) Native.loadLibrary( "C:\\WINDOWS\\system32\\PowrProf.dll", PowrProf.class); /* typedef struct { ULONG Granularity; ULONG Capacity; }BATTERY_REPORTING_SCALE, *PBATTERY_REPORTING_SCALE; */ public static class BATTERY_REPORTING_SCALE extends Structure { public long Granularity; public long Capacity; } /* typedef struct { BOOLEAN PowerButtonPresent; BOOLEAN SleepButtonPresent; BOOLEAN LidPresent; BOOLEAN SystemS1; BOOLEAN SystemS2; BOOLEAN SystemS3; BOOLEAN SystemS4; BOOLEAN SystemS5; BOOLEAN HiberFilePresent; BOOLEAN FullWake; BOOLEAN VideoDimPresent; BOOLEAN ApmPresent; BOOLEAN UpsPresent; BOOLEAN ThermalControl; BOOLEAN ProcessorThrottle; BYTE ProcessorMinThrottle; BYTE ProcessorMaxThrottle; BOOLEAN FastSystemS4; BYTE spare2[3]; BOOLEAN DiskSpinDown; BYTE spare3[8]; BOOLEAN SystemBatteriesPresent; BOOLEAN BatteriesAreShortTerm; BATTERY_REPORTING_SCALE BatteryScale[3]; SYSTEM_POWER_STATE AcOnLineWake; // enum SYSTEM_POWER_STATE SoftLidWake; SYSTEM_POWER_STATE RtcWake; SYSTEM_POWER_STATE MinDeviceWakeState; SYSTEM_POWER_STATE DefaultLowLatencyWake; }SYSTEM_POWER_CAPABILITIES, *PSYSTEM_POWER_CAPABILITIES; */ public static class SYSTEM_POWER_CAPABILITIES extends Structure { public boolean PowerButtonPresent; public boolean SleepButtonPresent; public boolean LidPresent; public boolean SystemS1; public boolean SystemS2; public boolean SystemS3; public boolean SystemS4; public boolean SystemS5; public boolean HiberFilePresent; public boolean FullWake; public boolean VideoDimPresent; public boolean ApmPresent; public boolean UpsPresent; public boolean ThermalControl; public boolean ProcessorThrottle; public int ProcessorMinThrottle; public int ProcessorMaxThrottle; public boolean FastSystemS4; public int spare2[] = new int[3]; public boolean DiskSpinDown; public int spare3[] = new int[8]; public boolean SystemBatteriesPresent; public boolean BatteriesAreShortTerm; public BATTERY_REPORTING_SCALE BatteryScale[] = new BATTERY_REPORTING_SCALE[3]; public int AcOnLineWake; public int SoftLidWake; public int RtcWake; public int MinDeviceWakeState; public int DefaultLowLatencyWake; } // http://msdn.microsoft.com/en-us/library/aa372691(VS.85).aspx void GetPwrCapabilities( SYSTEM_POWER_CAPABILITIES result ); } public static void main( String[] args ) { PowrProf lib2 = PowrProf.INSTANCE; PowrProf.SYSTEM_POWER_CAPABILITIES systemPOWERCAPABILITIES = new PowrProf.SYSTEM_POWER_CAPABILITIES(); lib2.GetPwrCapabilities(systemPOWERCAPABILITIES); System.out.println("Lid present:" + systemPOWERCAPABILITIES.LidPresent); } } 

对于枚举,C ++和Java之间的语法没有太大区别。

 enum eFtUsbDeviceStatus { eFtUsbDeviceNotShared, eFtUsbDeviceSharedActive, eFtUsbDeviceSharedNotActive, eFtUsbDeviceSharedNotPlugged, eFtUsbDeviceSharedProblem } 

您可以将其引用为eFtUsbDeviceStatus。