Cómo asignar enumeración en JNA
Pregunta
Tengo el siguiente enumeración ¿Cómo puedo asignar en jña ??
Esta enumeración se hace referencia adicionalmente en la estructura.
typedef enum
{
eFtUsbDeviceNotShared,
eFtUsbDeviceSharedActive,
eFtUsbDeviceSharedNotActive,
eFtUsbDeviceSharedNotPlugged,
eFtUsbDeviceSharedProblem
} eFtUsbDeviceStatus;
Abdul Khaliq
Solución
Si está utilizando JNA es probable que desee especificar explícitamente los valores de la enumeración en Java. Por defecto, el tipo de enumeración básica de Java no realmente te dan esa funcionalidad, hay que añadir un constructor para una EnumSet (ver este y este ).
Una manera simple para codificar C enumeraciones es utilizar ints const public static final envueltos en una clase con el mismo nombre que la enumeración. Se obtiene la mayor parte de la funcionalidad que se obtiene de una enumeración de Java, pero un poco menos sobrecarga asignar valores.
Algunos buenos ejemplos JNA, incluyendo los fragmentos siguientes (que fueron copiados) están disponibles href="http://code.google.com/p/jnaerator/wiki/Documentation" aquí .
Supongamos que el código C se ve así:
enum Values {
First,
Second,
Last
};
A continuación, el Java se parece a:
public static interface Values {
public static final int First = 0;
public static final int Second = 1;
public static final int Last = 2;
}
Otros consejos
En mi blog escribí una forma cómoda de usar real Java con enum
s JNA , en lugar de simplemente int
s arbitrarias. Es un poco más complejo, pero tiene varias ventajas:
- Se obtiene más del tipo de seguridad y de prevención de errores
- El IDE puede sugerir / autocompletar cosas
- Usted puede hacer una gran clase-IER y la API de Java más fácil
Básicamente, es necesario utilizar un TypeConverter
la enum
, y proporcionar que para JNA través de un simple TypeMapper
. La mayor parte del código adicional es evitar la necesidad de hacer una TypeConverter
separada para cada clase enum
diferente. (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, ver las definiciones y usos de HlTypeMapper , EnumConverter , y JnaEnum .
Al hacer referencia a esta enumeración en su estructura, lo que desea es declararlo como un int, no eFtUsbDeviceStatus ni nada de eso. Como un ejemplo ver 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);
}
}
No hay mucha diferencia en la sintaxis entre C ++ y Java para una enumeración.
enum eFtUsbDeviceStatus {
eFtUsbDeviceNotShared,
eFtUsbDeviceSharedActive,
eFtUsbDeviceSharedNotActive,
eFtUsbDeviceSharedNotPlugged,
eFtUsbDeviceSharedProblem
}
Puede hacer referencia a ella como eFtUsbDeviceStatus.