Java JNI 生成

in with 0 comment

有个比较奇怪的想法,windows系统通过java代码获取当前桌面的某些应用的坐标,继而利用robot来操作界面。

问题

好吧,在一番搜索之后发现java原生或许没有这个功能,只能求助于JNI,通过调用 C/C来实现。 这里记录一下JNI的生成过程以及FindWindow()方法的调用。。。(本人未使用过C/C,代码里可能有错误)。

创建Java类

public class WindowsUtil {
	static {
		System.loadLibrary("WindowsUtil");
	}
	public native String getXY(String title);
	
	public static void main(String[] args) {
		WindowsUtil util = new WindowsUtil();
		System.out.println(util.getXY("123"));;
	}
}

这里 WindowsUtil 是之后我们要生成的dll文件名。 getXY()是 JNI的调用方法。 这里的参数title,在后面没有用到。。。可以不写,相应的头文件和cpp文件把这个参数删去。

创建头文件

打开cmd,切换到java文件所在目录。

javac -h . WindowsUtil.java

我这里使用的是 jdk12, 如果是jdk8的话请用 javah 之后会在当前目录下生成class文件和.h头文件。

创建C/C++项目

因为本文没有从事过C/C++开发,这里应该有坑。。。。 本来是计划简单的使用VS Code和clang/mingw64来编译的,奈何基础知识不够,放弃。。。继而使用Visual Studio2019。

  1. 新建 《MFC动态链接库》项目,用来生成.dll文件
  2. 修改运行环境为x64(根据个人情况)
  3. 添加java 的 JNI 头文件目录(项目属性--> VC++目录-->包含目录-->添加jdk/include/win32 和 jdk/include)
  4. 新建 cpp文件
#include "pch.h"
#include "com_sxhjhf_robot_WindowsUtil.h"


JNIEXPORT jstring JNICALL Java_com_sxhjhf_robot_WindowsUtil_getXY
(JNIEnv* env, jobject obj, jstring str)
{
	HWND hwnd;
	RECT rect;
	CString sstr;
	CString ssstr;
	char szTitle[MAX_PATH];
	hwnd = FindWindow(_T("SWT_Window0"), NULL);

	if (NULL != hwnd)
	{
		GetWindowText(hwnd, (LPWSTR)(LPCTSTR)(szTitle), MAX_PATH);
		GetWindowRect(hwnd, &rect);
		sstr.Format(_T("%s ??? %d %d %d %d \n"), szTitle, rect.top, rect.right, rect.bottom, rect.left);
		ssstr = sstr;
		while (NULL != hwnd)
		{
			hwnd = ::FindWindowEx(NULL, hwnd, _T("SWT_Window0"), NULL);
			if (NULL != hwnd)
			{
				GetWindowRect(hwnd, &rect);
				GetWindowText(hwnd, (LPWSTR)(LPCTSTR)(szTitle), MAX_PATH);
				sstr.Format(_T("%s ??? %d %d %d %d \n"), szTitle, rect.top, rect.right, rect.bottom, rect.left);
				ssstr = ssstr + sstr;
			}
		}
	}
	//int w = rect.right - rect.left, h = rect.bottom - rect.top;
	//MoveWindow(hwnd, 100, 100, w, h, false);
	USES_CONVERSION;
	char* chars = T2A(ssstr);
	return env->NewStringUTF(chars);
}

  1. 生成dll
  2. 将生成的dll文件放入jdk/bin下面
  3. 运行java程序 输出结果如下
e_space - robot/src/main/java/com/sxhjhf/robot/WindowsUtil.java - Eclipse IDE ??? -8 3848 1048 1912 
e_space2 - Eclipse IDE ??? 89 2939 818 1915 
PartRenderingEngine's limbo ??? 10000 1440 10759 0 
SWT_Window_Eclipse ??? 0 136 39 0 
PartRenderingEngine's limbo ??? 10000 1440 10759 0 
SWT_Window_Eclipse ??? 0 136 39 0