【问题标题】:How do I properly map a `MagImageScalingCallback` using JNA?如何使用 JNA 正确映射“MagImageScalingCallback”?
【发布时间】:2015-12-08 18:21:20
【问题描述】:

我在我的 Java 项目中使用 jna.jar、jna-3.2.5.jar 和 jna-3.3.0-platform.jar。

这是我要复制的 Winapi 函数。

BOOL WINAPI MagImageScalingCallback(
  _In_  HWND           hwnd,
  _In_  void           *srcdata,
  _In_  MAGIMAGEHEADER srcheader,
  _Out_ void           *destdata,
  _In_  MAGIMAGEHEADER destheader,
  _In_  RECT           unclipped,
  _In_  RECT           clipped,
  _In_  HRGN           dirty
);

这是我的 Java 代码

public interface MagImageScalingCallback extends StdCallLibrary.StdCallCallback{
    public boolean MagImageScalingCallback(HWND hwnd,
            Pointer srcdata,
            MAGIMAGEHEADER.ByValue srcheader,
            Pointer destdata,
            MAGIMAGEHEADER.ByValue destheader,
            RectByValue source,
            RectByValue clipped,
            HRGN dirty);
}

当我进入这个回调方法时,我得到了意想不到的结果:

    public boolean MagImageScalingCallback(HWND hwnd, Pointer srcdata,
            MAGIMAGEHEADER.ByValue srcheader, Pointer destdata,
            MAGIMAGEHEADER.ByValue destheader, RectByValue source, RectByValue clipped, HRGN dirty) {
        image.setRGB(0, 0, srcheader.width, srcheader.height, srcdata.getIntArray(0, srcheader.width * srcheader.height ), 0, srcheader.width);
        return true;
    }

此表说明了当我更改变量的数据类型时,在 32 位和 64 位系统中哪些有效,哪些无效。

+--------------+--------------+-------------+-------------+
| Parameter    | Data type    |   64 bit    |   32 bit    |
+--------------+--------------+-------------+-------------+
| source       | WinDef.RECT  |   Working   | Not Working |
| clipped      | WinDef.RECT  |   Working   | Not Working |
| source       | RectByValue  |   Working   |   Working   |
| source       | RectByValue  |   Working   |   Working   |
| srcdata      | Pointer      |   Working   | Not Working |
| destdata     | Pointer      |   Working   | Not Working |
+--------------+--------------+-------------+-------------+

不工作意味着结果中的图像全黑

如果我在 64 位系统中使用上述代码,我可以捕获桌面(我可以从 Pointer 变量中访问数据)。如果我在 32 位系统中使用相同的代码,我不会得到任何图像。可以看my whole code

为什么我的代码中有错误?我该如何解决?

供您参考。正如您在screenSkip.java 中看到的,每当调用 MagSetWindowSource 函数时。调用 MagImageScalingCallback(第 80 行)。

这个section of code的问题

如果我在 64 位系统上运行此代码 srcdatadestdata 将保存桌面的整数像素数组(如果我将其保存为图像,它会捕获桌面)。但是如果我在 32 位系统上运行相同的代码,这两个变量数组的像素值总是为零(如果我保存图像,它总是黑色的)

64 位系统

32 位系统

@david-heffernan 我在 32 位系统上运行此代码。我知道The Magnification API is not supported under WOW64;。这意味着 32 位放大应用程序适用于 32 位系统,而 64 位放大应用程序适用于 64 位系统。请停止评论放大 API 不适用于 WOW64 并尝试在 32 位系统上执行此代码。

根据您的要求,下图显示了我系统的配置。

【问题讨论】:

  • 您要复制的C 成语是什么? struct 处理是通过引用 (struct *) 处理参数和值 (struct) 在聚合字段中。 Java Structure 标记接口(@98​​7654343@、ByReference)用于强制补充约定。所有其他值都是按值传递的,com.sun.jna.ptr 包中存在一系列 ByReference 实现,以方便传递值的“地址”。
  • @technomage 我已经更新了这个问题。如果您不明白,请联系我。
  • Pointer 总是按值传递。无论是 64 位还是 32 位,如果本机签名要求按值传递结构,则需要按值传递它(传递 struct* 碰巧在您的 64 位情况下起作用,这是由于如何编译器处理传递小的struct 值)。
  • @technomage 我该如何解决这个问题?
  • 如果您使用 SIZE_T 类型,JNA 应该注意大小差异(假设您指的是 MAGIMAGEHEADER 中的 cbSize 字段)。从SO link above,我不希望它在 64 位窗口上以 32 位模式工作。

标签: java pointers winapi jna


【解决方案1】:

回调是正确的——你的代码没有任何缺陷,除了你使用了不推荐使用的函数。

考虑使用这个:

try {
    Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
    BufferedImage  capture = new Robot().createScreenCapture(screenRect);
    ImageIO.write(capture, "JPEG", new File("printed1.jpg"));
} catch (Exception e) {
    e.printStackTrace();
}

【讨论】:

  • 我想跳过一些窗口进行捕获。你的答案是一个非常基本的代码。
  • 您仍然可以使用部分代码来确定要抓取的矩形。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-22
  • 1970-01-01
  • 2019-04-12
  • 1970-01-01
  • 2015-02-14
  • 1970-01-01
相关资源
最近更新 更多