【发布时间】: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 位系统上运行此代码 srcdata 和 destdata 将保存桌面的整数像素数组(如果我将其保存为图像,它会捕获桌面)。但是如果我在 32 位系统上运行相同的代码,这两个变量数组的像素值总是为零(如果我保存图像,它总是黑色的)
@david-heffernan 我在 32 位系统上运行此代码。我知道The Magnification API is not supported under WOW64;。这意味着 32 位放大应用程序适用于 32 位系统,而 64 位放大应用程序适用于 64 位系统。请停止评论放大 API 不适用于 WOW64 并尝试在 32 位系统上执行此代码。
根据您的要求,下图显示了我系统的配置。
【问题讨论】:
-
您要复制的
C成语是什么?struct处理是通过引用 (struct *) 处理参数和值 (struct) 在聚合字段中。 JavaStructure标记接口(@987654343@、ByReference)用于强制补充约定。所有其他值都是按值传递的,com.sun.jna.ptr包中存在一系列ByReference实现,以方便传递值的“地址”。 -
@technomage 我已经更新了这个问题。如果您不明白,请联系我。
-
Pointer总是按值传递。无论是 64 位还是 32 位,如果本机签名要求按值传递结构,则需要按值传递它(传递struct*碰巧在您的 64 位情况下起作用,这是由于如何编译器处理传递小的struct值)。 -
@technomage 我该如何解决这个问题?
-
如果您使用
SIZE_T类型,JNA 应该注意大小差异(假设您指的是MAGIMAGEHEADER中的 cbSize 字段)。从SO link above,我不希望它在 64 位窗口上以 32 位模式工作。