使用JNA调用API控制台函数

官方的API函数调用介绍网站:

https://docs.microsoft.com/en-us/windows/console/console-reference

首先要使用native定义方法,引用到“kernel32”之内的方法。

static {
		Native.register("kernel32");
	}

最重要的再定义并利用GetStdHandle方法来检索指定标准设备的句柄(具体用来干嘛的不是很清楚,但是我后续所用方法,必须传输该方法获取到的值)

然后需要定义需要用到的方法,例如GetConsoleScreenBufferInfo“获取控制台屏幕缓冲区的信息”:

static native boolean GetConsoleScreenBufferInfo(int hConsoleOutput,
			PCONSOLE_SCREEN_BUFFER_INFO.ByReference lpConsoleScreenBufferInfo);

注意参数的类型定义,我就着这和另一个同事研究了三天,才发现一直没效果的原因是因为参数问题。

例如PCONSOLE_SCREEN_BUFFER_INFO类型:

public static class PCONSOLE_SCREEN_BUFFER_INFO extends Structure {

		public static class ByReference extends PCONSOLE_SCREEN_BUFFER_INFO implements Structure.ByReference {
		}

		public static class ByValue extends PCONSOLE_SCREEN_BUFFER_INFO implements Structure.ByValue {
		}

		public COORD.ByValue dwSize = new COORD.ByValue();
		public COORD.ByValue dwCursorPosition = new COORD.ByValue();
		public short wAttributes;
		public SMALL_RECT.ByValue srWindow = new SMALL_RECT.ByValue();
		public COORD.ByValue dwMaximumWindowSize = new COORD.ByValue();

		@Override
		protected List getFieldOrder() {
			return Arrays.asList("dwSize", "dwCursorPosition", "wAttributes", "srWindow", "dwMaximumWindowSize");
		}
	}

这当中ByReference与ByValue非常重要,后续传值时必须搞清楚,哪个是方法的值传递还是引用传递。一般来说当传递整个对象时一般使用引用传递,当获取改变对象内某些参数时,使用的是值传递。

例如使用GetConsoleScreenBufferInfo方法获取控制台光标位置的方法:

public static COORD.ByValue getPointer(int handle) {
		WinKernel32.PCONSOLE_SCREEN_BUFFER_INFO.ByReference lpConsoleScreenBufferInfo = new WinKernel32.PCONSOLE_SCREEN_BUFFER_INFO.ByReference();
		if (!WinKernel32.GetConsoleScreenBufferInfo(handle, lpConsoleScreenBufferInfo)) {
			checkLastError();
		}
		return lpConsoleScreenBufferInfo.dwCursorPosition;
	}

 

COORD.ByValue pointer = getPointer(hOut);//hOut为GetStdHandle所获取的值
pointer.x;//为获取的坐标类型为SHORT,该类型不是java中的short
pointer.y;//而是import com.sun.jna.platform.win32.WinDef.SHORT;

以上为个人总结与理解,如有偏差欢迎指点

你可能感兴趣的:(java,JNA,API,JNA,API)