Comment la carte ENUM dans la JNA
Question
Je le ENUM suivant comment i dans mapper ?? jna
Cette ENUM est encore référencé dans la structure.
typedef enum
{
eFtUsbDeviceNotShared,
eFtUsbDeviceSharedActive,
eFtUsbDeviceSharedNotActive,
eFtUsbDeviceSharedNotPlugged,
eFtUsbDeviceSharedProblem
} eFtUsbDeviceStatus;
Abdul Khaliq
La solution
Si vous utilisez la JNA que vous voulez sans doute de préciser explicitement les valeurs de l'énumération en Java. Par défaut, le type de base de Java ENUM ne vous donne pas vraiment cette fonctionnalité, vous devez ajouter un constructeur pour un EnumSet (voir cette et cette ).
Une façon simple de coder C énumérations est d'utiliser ints const public static final enveloppé dans une classe avec le même nom que le ENUM. Vous obtenez la plupart des fonctionnalités que vous obtiendrez d'un enum Java, mais un peu moins frais généraux d'attribuer des valeurs.
Quelques exemples de bonne JNA, y compris les extraits ci-dessous (qui ont été copiés) sont disponibles href="http://code.google.com/p/jnaerator/wiki/Documentation" ici .
Supposons que votre code C ressemble à:
enum Values {
First,
Second,
Last
};
Alors Java ressemble à:
public static interface Values {
public static final int First = 0;
public static final int Second = 1;
public static final int Last = 2;
}
Autres conseils
Sur mon blog, j'ai écrit un moyen pratique d'utiliser de véritables Java enum
s avec JNA , plutôt que int
s simplement arbitraires. Il est un peu plus complexe, mais il présente plusieurs avantages:
- Vous obtenez plus du type sécurité et la prévention des erreurs
- Votre IDE peut suggérer / choses autocomplete
- Vous pouvez faire beaucoup de classe et plus facile ier API Java
En gros, vous devez utiliser un TypeConverter
le enum
et prévoit que la JNA par un simple TypeMapper
. La plupart du code supplémentaire est d'éviter un besoin de faire TypeConverter
pour chaque autre classe enum
. (Dans mon cas, je devais faire beaucoup d'entre eux.)
Vous pouvez voir le code monde réel dans mon projet jhllib . regarder, en particulier, les définitions et les usages de HlTypeMapper , EnumConverter et JnaEnum .
Lorsque vous faites référence dans votre ENUM cette structure, vous voulez juste de le déclarer comme un entier, non eFtUsbDeviceStatus ou quelque chose comme ça. A titre d'exemple, voir AcOnLineWake ci-dessous:
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);
}
}
Il n'y a pas beaucoup de différence dans la syntaxe entre C ++ et Java pour un ENUM.
enum eFtUsbDeviceStatus {
eFtUsbDeviceNotShared,
eFtUsbDeviceSharedActive,
eFtUsbDeviceSharedNotActive,
eFtUsbDeviceSharedNotPlugged,
eFtUsbDeviceSharedProblem
}
Vous pouvez faire référence comme eFtUsbDeviceStatus.