Как отобразить enum в JNA - PullRequest
9 голосов
/ 21 июля 2009

У меня есть следующее enum, как мне отобразить в jna ??

Это перечисление далее упоминается в структуре.

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

Абдул Халик

Ответы [ 4 ]

11 голосов
/ 31 августа 2009

Если вы используете JNA, вы, вероятно, захотите явно указать значения перечисления в Java. По умолчанию базовый тип перечисления Java на самом деле не предоставляет вам такой функциональности, вам нужно добавить конструктор для EnumSet (см. this и this ).

Простой способ кодировать перечисления C - это использовать открытые статические конечные константы, заключенные в класс с тем же именем, что и перечисление. Вы получаете большую часть функциональности, которую вы получаете от перечисления Java, но немного меньше накладных расходов для назначения значений.

Несколько хороших примеров JNA, включая приведенные ниже фрагменты (которые были скопированы), доступны здесь .

Предположим, ваш код 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;
}
7 голосов
/ 03 декабря 2010

В своем блоге я написал удобный способ использовать real Java enum s с JNA , а не просто произвольные int s. Это немного сложнее, но имеет несколько преимуществ:

  • Вы получаете большинство типов безопасности и предотвращения ошибок
  • Ваша IDE может предлагать / автозаполнять вещи
  • Вы можете сделать намного более простой и удобный Java API

Как правило, вам нужно использовать пользовательский TypeConverter для enum и передать его JNA через простой TypeMapper. Большая часть дополнительного кода состоит в том, чтобы не создавать отдельного TypeConverter для каждого отдельного enum класса. (В моем случае я должен был сделать их много.)


Вы можете увидеть некоторый реальный код в моем проекте jhllib . В частности, посмотрите на определения и использование HlTypeMapper , EnumConverter и JnaEnum .

2 голосов
/ 10 марта 2010

Когда вы ссылаетесь на это перечисление в своей структуре, вы просто хотите объявить его как 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);
    }
}
0 голосов
/ 31 июля 2009

Нет большой разницы в синтаксисе между C ++ и Java для перечисления.

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

Вы можете ссылаться на него как eFtUsbDeviceStatus.

...