2009-07-21 10 views
8

Tôi có enum sau đây làm thế nào để tôi bản đồ trong jna ??Làm thế nào để ánh xạ enum trong JNA

Enum này được tham chiếu thêm trong cấu trúc.

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

Abdul Khaliq

Trả lời

11

Nếu bạn đang sử dụng JNA, bạn có thể muốn chỉ định rõ ràng các giá trị của liệt kê trong Java. Theo mặc định, kiểu enum cơ bản của Java không thực sự cung cấp cho bạn chức năng đó, bạn phải thêm một hàm tạo cho một EnumSet (xem thisthis).

Một cách đơn giản để mã hóa C liệt kê là sử dụng công thức tĩnh int const cuối cùng được bọc trong một lớp có cùng tên với enum. Bạn nhận được hầu hết các chức năng mà bạn nhận được từ một enum Java nhưng chi phí thấp hơn một chút để gán các giá trị.

Một số ví dụ JNA tốt, bao gồm các đoạn dưới đây (được sao chép) có sẵn here.

Giả mã C của bạn trông giống như:

enum Values { 
    First, 
    Second, 
    Last 
}; 

Sau đó, Java trông giống như:

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

Không có nhiều sự khác biệt về cú pháp giữa C++ và Java cho một enum.

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

Bạn có thể tham chiếu nó dưới dạng eFtUsbDeviceStatus.

2

Khi tham khảo enum này trong cấu trúc của bạn, bạn chỉ muốn khai báo nó như một int, không eFtUsbDeviceStatus hoặc bất kỳ thứ gì tương tự. Như một ví dụ thấy AcOnLineWake dưới đây:

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

Trên blog của tôi, tôi đã viết lên a convenient way to use real Java enums with JNA, chứ không phải chỉ tùy ý int s. Nó phức tạp hơn một chút, nhưng nó có một số ưu điểm:

  • Bạn nhận được nhất loại an toàn và không bị lỗi ngăn ngừa
  • IDE của bạn có thể đề nghị/autocomplete điều
  • Bạn có thể làm cho một nhiều đẳng cấp IER và dễ dàng hơn Java API

về cơ bản, bạn cần phải sử dụng một tùy chỉnh TypeConverter cho enum, và cung cấp đó để JNA thông qua một đơn giản TypeMapper. Hầu hết mã bổ sung là để tránh phải thực hiện một riêng biệt TypeConverter cho mỗi lớp khác nhau enum. (Trong trường hợp của tôi, tôi phải tạo ra rất nhiều.)


Bạn có thể thấy một số mã thực trong dự án jhllib của mình. Cụ thể, hãy xem các định nghĩa và cách sử dụng của HlTypeMapper, EnumConverterJnaEnum.