【问题标题】:C struct to Java JNA Structure (pointer to struct)C 结构到 Java JNA 结构(指向结构的指针)
【发布时间】:2016-04-20 14:37:48
【问题描述】:

我对基于 C/C++ 结构的 JNA 结构有疑问。字段 nScreenIndex、uVendorID、uProductID、uVersionNumber 看起来不错,但在它们之后我看到奇数字节。我的主要和唯一目标是“提取” pMonitor 字段。 pMonitor 声明和 MONITOR 实现是否正确?

C/C++ 来源:

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;

和 Java/JNA 代码:

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 {
    };
}

【问题讨论】:

  • pCWndBeamHandler 应该是 Pointer,而不是 PointerByReference。您还应该为每个Structure 添加一个基于Pointer 的构造函数,该构造函数在super() 之后调用Structure.read()(不是关键,但可以避免不必要的额外内存分配)。

标签: java c struct structure jna


【解决方案1】:

你非常接近正确。

在java中的SCREEN类中,需要将pMonitor定义为:

    public MONITOR.ByReference pMonitor;

这是per the FAQ

什么时候应该使用 Structure.ByReference?结构.按值?结构[]?

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

作为附录:

当我使用 mingw 编译的 dll 将其存根时,我必须从 StdCallLibrary 而不是 Library 继承 - 这对你来说可能不是这样,我只是提到这一点,因为它影响了我的测试.

【讨论】:

  • 谢谢,现在可以完美运行了。有两个问题:缺少“.ByReference”和结构中的错误(默认)数据对齐。我不得不将 MONITOR 更改为 MONITOR.ByReference 并将 super() 更改为 super(ALIGN_NONE)。 ALIGN_NONE 设置结构不对齐,将所有字段放在最近的 1 字节边界上。
  • C++ 代码中没有任何内容表明它正在使用 8 位打包;但很高兴它对你有用。像这样更改的打包规则非常少见——在提到的 C++ 接口中没有任何内容表明情况如此。
  • 我没有 C/C++ 源代码 - 我只有 *.dll 和 *.h 文件,但看起来 Elo Touch Solutions 开发人员使用 1 字节对齐的触摸屏 API。
  • 顺便说一句:有没有办法为 JNA 库(*.dll Java 包装器)中的所有数据结构设置全局内存字节对齐?目前我正在以非常笨拙的方式执行此操作 - 我在每个结构中设置数据对齐 (super(ALIGN_NONE))(许多结构位于单独的文件中)。 stackoverflow.com/questions/36809144/…
猜你喜欢
  • 2012-03-28
  • 2011-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
  • 2021-04-01
  • 2017-07-13
相关资源
最近更新 更多