Kotlin JNA 调用 Win32 API 示例(GetCursorPos)

JNA (Java Native Access)

JNA(Java Native Access)是一个改进了JNI的开源(GPL)的Java框架,曾经由SUN公司主导开发的,用于使Java调用原生接口。

使用JNA调用Win32 API

本示例使用Kotlin环境和Gradle(Kotlin DSL)构建

1.添加JNA依赖

在build.gradle.kts中添加

implementation("net.java.dev.jna:jna:latest.release")

2.查阅Win32 API

我们以GetCursorPos这个Win32API为例,它接收一个结构体指针,将其修改为鼠标指针的位置:

//代码经过部分修改以显得更直观
typedef struct {
  int x;
  int y;
} POINT, *PPOINT;

BOOL GetCursorPos(LPPOINT lpPoint);

映射数据结构

首先,我们将结构体POINT映射为Kotlin代码

import com.sun.jna.Native
import com.sun.jna.Structure
import com.sun.jna.Library

open class POINT() :Structure() {
    @JvmField var x: Int = 0
    @JvmField var y: Int = 0
    override fun getFieldOrder(): MutableList<String>?
        = mutableListOf("x","y")
}

注意:

  1. 由于Kotlin和Java的类略有不同,需加@JvmField注解,否则会遇到class has unknown or zero size (ensure all fields are public)Structure.getFieldOrder() on class X returns names XXXX which do not match declared field names ([])这样的错误
  2. C语言的结构体成员在内存中是有顺序的,在Kotlin中需重载getFieldOrder函数来表述顺序信息

然后将他的指针(引用)LPPOINT映射为Kotlin代码,只需继承POINT类和Structure.ByReference接口即可

class LPPOINT :POINT(), Structure.ByReference

映射函数接口

需在jna.Library的子类中建立一个同名同类型的函数:

interface MyLib :Library {
    fun GetCursorPos(lpPoint :LPPOINT) :Boolean
}

加载DLL

val LIBRARY :MyLib = Native.load("user32", MyLib::class.java)

调用API

var lpPoint = LPPOINT()
val r = LIBRARY.GetCursorPos(lpPoint)
print("${lpPoint.x},${lpPoint.y}\r")

完整代码

import com.sun.jna.Native
import com.sun.jna.Structure
import com.sun.jna.Library

open class POINT(@JvmField var x: Int = 0, @JvmField var y: Int = 0) :Structure() {
    override fun getFieldOrder(): MutableList<String>? = mutableListOf("x","y")
}

class LPPOINT :POINT(), Structure.ByReference

interface MyLib :Library {
    fun GetCursorPos(lpPoint :LPPOINT) :Boolean
}

fun main() {
    val LIBRARY :MyLib = Native.load("user32", MyLib::class.java)

    var lpPoint = LPPOINT()
    while (true) {
        val r = LIBRARY.GetCursorPos(lpPoint)
        print("${lpPoint.x},${lpPoint.y}\r")
    }
}

参考资料

JNA官方文档

环境

项目 版本
Kotlin 1.6.10
JDK OpenJDK 17
Gradle 7.3
JNA 5.10.0
上一篇:Kotlin在Android开发中那些让人舒适的地方,android应用开发基础教程


下一篇:Android-Kotlin-区间与FOR&LIST&MAP简单使用,我的Android春季历程