2016-04-20 18 views
0

Ich habe ein Problem mit JNA-Struktur basierend auf C/C++ - Struktur. Felder nScreenIndex, uVendorID, uProductID, uVersionNumber sieht OK, aber nach ihnen sehe ich ungerade Bytes. Mein wichtigstes und einziges Ziel ist es, pMonitor-Felder zu "extrahieren". Sind pMonitor Erklärung und MONITOR Implementierung korrekt?C-Struktur zu Java-JNA-Struktur (Zeiger auf Struktur)

C/C++ Herkunft:

SCREEN* EloGetScreenByIndex (int nScreenIndex); 

typedef struct SCREEN_TAG 
{ 
    int    nScreenIndex; 
    USHORT   uVendorID;  
    USHORT   uProductID;  
    USHORT   uVersionNumber; 
    wchar_t   szDevicePath [MAX_PATH]; 
    HANDLE   hCalTouchThread; 
    MONITOR*   pMonitor; 
    LPVOID   pCWndBeamHandler; 
    BOOL    bIrBeams; 
} SCREEN; 

typedef struct MONITORS_TAG 
{ 
    int  elo_mon_num; 
    int  x; 
    int  y; 
    int  width; 
    int  height; 
    DWORD orientation; 
    bool is_primary; 
} MONITOR; 

und Java/JNA Code:

SCREEN EloGetScreenByIndex(int nScreenIndex); 

public class SCREEN extends Structure { 
    public int nScreenIndex; 
    public short uVendorID; 
    public short uProductID; 
    public short uVersionNumber; 
    public char[] szDevicePath = new char[WinDef.MAX_PATH]; 
    public WinNT.HANDLE hCalTouchThread; 
    public MONITOR pMonitor; 
    public PointerByReference pCWndBeamHandler; 
    public boolean bIrBeams; 
    ... 
} 

public class MONITOR extends Structure { 
    public int elo_mon_num; 
    public int x; 
    public int y; 
    public int width; 
    public int height; 
    public int orientation; 
    public byte is_primary; 

    public MONITOR() { 
     super(); 
    } 

    @Override 
    protected List<? > getFieldOrder() { 
     return Arrays.asList("elo_mon_num", "x", "y", "width", "height", "orientation", "is_primary"); 
    } 

    public MONITOR(Pointer peer) { 
     super(peer); 
    } 

    public static class ByReference extends MONITOR implements Structure.ByReference { 
    }; 

    public static class ByValue extends MONITOR implements Structure.ByValue { 
    }; 
} 
+0

'pCWndBeamHandler' sollte' Pointer', nicht 'PointerByReference' sein. Sie sollten auch einen 'Pointer'-basierten Konstruktor für jede' Struktur' hinzufügen, der 'Structure.read()' nach 'super()' aufruft (nicht kritisch, aber vermeidet unnötige zusätzliche Speicherzuweisungen). – technomage

Antwort

2

Du bist so ganz in der Nähe richtig.

in der Screen-Klasse in Java, müssen Sie pMonitor definieren:

public MONITOR.ByReference pMonitor; 

Diese per the FAQ ist.

Wann sollte ich Structure.ByReference verwenden? Struktur.ByValue? Struktur[]?

typedef struct _outerstruct2 { 
    simplestruct *byref; // use Structure.ByReference 
} outerstruct2; 

Als Nachtrag:

Als ich dies eine mingw dll zusammengestellt mit stubbed, hatte ich von StdCallLibrary und nicht Library erben - das ist für Sie nicht der Fall sein kann, ich Ich erwähne das nur, weil es meine Tests beeinflusst hat.

+0

Danke, jetzt funktioniert es perfekt. Es gab zwei Probleme: fehlende ".ByReference" und schlechte (Standard) Datenausrichtung in Strukturen. Ich musste MONITOR in MONITOR.ByReference und Super() in Super (ALIGN_NONE) ändern. ALIGN_NONE setzen keine Ausrichtung auf Strukturen, platzieren Sie alle Felder auf nächste 1-Byte-Grenze. – jakson

+0

Es gibt nichts im C++ - Code, der anzeigt, dass es 8-Bit-Packing verwendet; aber froh, dass es für dich funktioniert. Geänderte Packregeln wie diese sind ziemlich ungewöhnlich - es gibt nichts in der erwähnten C++ - Schnittstelle, das anzeigt, dass dies der Fall ist. – Petesh

+0

Ich habe keinen C/C++ Quellcode - ich habe nur * .dll und * .h Dateien, aber es sieht so aus, als ob die Entwickler von Elo Touch Solutions 1 Byte für ihre Touchscreen-API verwenden. – jakson

Verwandte Themen