Java 如何使用JNA正确映射“MagImageScalingCallback”?
我在Java项目中使用jna.jar、jna-3.2.5.jar和jna-3.3.0-platform.jar 这是我想要复制的Winapi函数Java 如何使用JNA正确映射“MagImageScalingCallback”?,java,pointers,winapi,jna,Java,Pointers,Winapi,Jna,我在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_ MA
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位系统中使用上述代码,我可以捕获桌面(我可以从指针变量访问数据)。如果我在32位系统中使用相同的代码,我不会得到任何图像。你可以看到
为什么我的代码中有错误?我怎样才能解决这个问题
供您参考。正如您在screenSkip.java
中所看到的,只要调用MagSetWindowSource函数。调用MagImageScalingCallback(第80行)
这方面的问题
如果我在64位系统上运行此代码,srcdata
和destdata
将保存桌面的整数像素数组(如果我将此保存为图像,它将捕获桌面)。但如果我在32位系统上运行相同的代码,这两个变量数组像素值始终为零(如果我保存图像,它始终为黑色)
64位系统
32位系统
@david heffernan我正在32位系统上运行此代码。我知道WOW64不支持放大API代码>。这意味着32位放大应用程序在32位系统上工作,而64位放大应用程序在64位系统上工作。请停止评论放大API在WOW64上不起作用,并尝试在32位系统上执行此代码
根据您的请求,下图显示了我的系统配置
回调是正确的-代码中没有缺陷,而且您使用的是不推荐使用的函数 考虑使用以下方法:
试试看{
矩形screenRect=新矩形(Toolkit.getDefaultToolkit().getScreenSize());
BuffereImage capture=new Robot().CreateScreateScreenCapture(screenRect);
写入(捕获,“JPEG”,新文件(“printed1.jpg”);
}捕获(例外e){
e、 printStackTrace();
}
您试图复制的C
习惯用法是什么<代码>结构处理是通过参数的引用(struct*
)和聚合字段中的值(struct
)进行的。Java结构
标记接口(ByValue
,ByReference
)用于强制执行补充约定。所有其他值都是按值传递的,在com.sun.jna.ptr
包中存在一系列ByReference
实现,以便于传递值的“地址”。@technomage我已经更新了问题。如果您不明白,请ping我。指针始终按值传递。无论是64位还是32位,如果本机签名要求按值传递结构,则需要按值传递(由于编译器如何处理传递较小的struct
值,传递struct*
碰巧在64位情况下起作用)@technomage如何解决此问题?如果您使用的是SIZE\u T
类型,JNA应注意大小差异(假设您指的是MAGIMAGEHEADER
中的cbSize字段)。从中,我不希望在64位windows上以32位模式工作。我希望从捕获中跳过一些窗口。您的答案是一个非常基本的代码。您仍然可以使用代码的某些部分来确定要抓取的矩形。