JNA从入门到精通-03功能描述

功能概述

JNA 的特定于平台的功能由libffi 库提供。在将 libffi 集成到 JNA(主要由 wmeissner 执行)之前,手动编码的程序集用于支持 linux、sparc、windows 和 Mac OSX(intel 和 PPC 目标)。libffi 库提供了一种抽象,用于使用任意类型的参数集调用任意目标地址。

ffi_prep_cif()调用描述了目标函数希望如何被调用,同时实际ffi_call()执行调用,提供由返回的 CIF 结构ffi_prep_cif()、参数数组和返回值的缓冲区。

接口映射

当您通过 实例化本机库接口时Native.load(),JNA 创建一个代理,该代理 invoke通过Library.Handler. 此方法查找 Function表示本机库导出的函数的适当对象。代理处理程序可以执行一些初始名称转换,以从调用的代理函数中导出实际的本地库函数名称。

找到对象后,将使用所有可用参数调用Function其泛型方法。invoke代理函数签名用于确定传入参数的类型和所需的返回类型。

Function对象执行任何必要的参数转换,将NativeMapped类型转换为其本机表示,或将 aTypeMapper应用于已注册TypeMapper 转换的任何传入类型。在函数返回时执行类似的转换。默认情况下,所有Structure对象的 Java 字段在本地函数调用之前都被复制到它们的本地内存中,并在调用之后被复制回来。

所有Function调用都根据其返回类型通过不同的本地方法进行路由,但所有这些本地方法都通过相同的dispatch调用 in分派native/dispatch.c。在构建供 libffi 使用的函数调用描述之前,该函数执行 Java 对象到本机表示的任何最终转换。

libffi 库需要目标函数的参数和返回类型的描述,以便执行适用于最终本机调用调用的特定于平台的堆栈构造。一旦 libffi 执行了本机调用(通过ffi_call()),它会将结果复制到 JNA 提供的缓冲区中,然后将其转换回适当的 Java 对象。

直接映射

nativeJNI 提供了注册一个本地函数,以便在从 Java 调用标记的方法时直接调用。JNA 使用 libffi 为通过Native.register()调用注册的每个本机方法构造代码存根(JNA 使用反射来标识native直接映射类中具有限定符的所有方法)。每个存根分派到 中的函数dispatch_direct ,native/dispatch.c并分配了一个关联的结构,该结构完全描述了函数调用,以避免在运行时产生任何反射成本。

中心dispatch_direct函数尝试将 Java 调用堆栈按原样传递给本机函数(同样,使用ffi_call()来自 libffi)。使用的非原始参数越多,直接分派就越需要做额外的工作来将 Java 对象转换为堆栈上的本机表示。理想的性能是通过仅使用原语或Pointer 参数来实现的。

你可能感兴趣的:(JNA从入门到精通-03功能描述)