2009-07-21 15 views
8

Tengo la siguiente enumeración ¿cómo puedo mapear en jna?Cómo mapear enum en JNA

Esta enumeración se referencia más en la estructura.

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

Abdul Khaliq

Respuesta

11

Si está utilizando JNA probablemente desee especificar explícitamente los valores de la enumeración en Java. De manera predeterminada, el tipo de enumeración básico de Java realmente no le da esa funcionalidad, debe agregar un constructor para un EnumSet (vea this y this).

Una forma simple de codificar enumeraciones en C es usar constints finales estáticos públicos envueltos en una clase con el mismo nombre que enum. Obtiene la mayor parte de la funcionalidad que obtendría de una enumeración Java pero un poco menos de sobrecarga para asignar valores.

Algunos buenos ejemplos de JNA, incluidos los fragmentos a continuación (que fueron copiados) están disponibles here.

Supongamos que el código C se parece a:

enum Values { 
    First, 
    Second, 
    Last 
}; 

luego mira el Java como:

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

No hay mucha diferencia en la sintaxis entre C++ y Java para una enumeración.

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

Puede consultarlo como eFtUsbDeviceStatus.

2

Al hacer referencia a esta enumeración en su estructura, lo que desea es declararlo como un int, no eFtUsbDeviceStatus o algo por el estilo. A modo de ejemplo, véase AcOnLineWake a continuación:

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

En mi blog escribí a convenient way to use real Java enums with JNA, en lugar de sólo arbitrarias int s. Es un poco más complejo, pero tiene varias ventajas:

  • Se obtiene más del tipo de seguridad y de prevención de errores
  • Su IDE puede sugerir/cosas autocompletar
  • se puede hacer una gran clase-IER y la API de Java más fácil

Básicamente, es necesario utilizar una costumbre TypeConverter para la enum, y disponer que a través de un simple JNA TypeMapper. La mayor parte del código adicional es para evitar tener que hacer un TypeConverter por separado para cada clase diferente enum. (En mi caso, tuve que hacer un montón de ellos.)


se puede ver algo de código del mundo real en mi proyecto jhllib. En particular, consulte las definiciones y usos de HlTypeMapper, EnumConverter y JnaEnum.