2009-07-21 13 views
8

Ho il seguente enum come faccio a mappare in jna ??Come mappare enum in JNA

Questa enumerazione viene ulteriormente citata nella struttura.

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

Abdul Khaliq

risposta

11

Se si sta utilizzando JNA, si consiglia di specificare esplicitamente i valori dell'enumerazione in Java. Per impostazione predefinita, il tipo di enum di base di Java non fornisce realmente tale funzionalità, è necessario aggiungere un costruttore per un EnumSet (vedere this e this).

Un modo semplice per codificare le enumerazioni C consiste nell'utilizzare i const const statici pubblici racchiusi in una classe con lo stesso nome dell'enum. Ottieni la maggior parte delle funzionalità ottenute da un enum Java, ma un po 'meno overhead per assegnare valori.

Alcuni buoni esempi JNA, inclusi i frammenti di seguito (che sono stati copiati) sono disponibili here.

Supponiamo che il vostro codice C si presenta come:

enum Values { 
    First, 
    Second, 
    Last 
}; 

Poi il Java assomiglia:

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

Non c'è molta differenza nella sintassi tra C++ e Java per un enum.

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

È possibile fare riferimento come eFtUsbDeviceStatus.

2

Quando riferimento a questo enum nella struttura, si vuole solo dichiararla come un int, non eFtUsbDeviceStatus o qualcosa del genere. A titolo di esempio vedere AcOnLineWake di seguito:

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

Sul mio blog ho scritto a convenient way to use real Java enums with JNA, piuttosto che solo arbitrari int s. E 'un po' più complesso, ma ha diversi vantaggi:

  • Si ottiene più del tipo di sicurezza e l'errore di prevenzione
  • vostro IDE può suggerire/cose di completamento automatico
  • si può fare una molto più class-Ier e più semplice API Java

in sostanza, è necessario utilizzare un costume TypeConverter per il enum, e prevedere che per JNA attraverso una semplice TypeMapper. La maggior parte del codice aggiuntivo consiste nell'evitare di dover creare un numero distinto TypeConverter per ciascuna classe enum diversa. (Nel mio caso, ho dovuto fare un sacco di loro.)


è possibile vedere alcuni codice del mondo reale nel mio progetto jhllib. In particolare, guarda le definizioni e gli usi di HlTypeMapper, EnumConverter e JnaEnum.