如何在JNA中映射枚举

时间:2009-07-21 07:53:34

标签: java enums native jna

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

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

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

Abdul Khaliq

5 个答案:

答案 0 :(得分:11)

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

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

一些好的JNA示例,包括下面的代码段(已复制)可用here

假设您的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;
}

答案 1 :(得分:7)

在我的博客上,我写了a convenient way to use real Java enums with JNA,而不是任意int。它有点复杂,但它有几个优点:

  • 您获得大多数类型安全和错误预防
  • 您的IDE可以建议/自动填充内容
  • 您可以制作更多类更简单,更简单的Java API

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


您可以在我的jhllib项目中看到一些真实世界的代码。请特别注意HlTypeMapperEnumConverterJnaEnum的定义和用法。

答案 2 :(得分:2)

在结构中引用此枚举时,您只想将其声明为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);
    }
}

答案 3 :(得分:0)

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

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

您可以将其引用为eFtUsbDeviceStatus。

答案 4 :(得分:0)

JNA 现在包含一个 EnumConverter