目录
简介function的定义Function的实际应用总结简介
在JNA中,为了和native的function进行映射,我们可以有两种mapping方式,第一种是interface mapping,第二种是direct mapping。虽然两种方式不同,但是在具体的方法映射中,我们都需要在JAVA中定义一个和native方法进行映射的方法。
而这个JAVA中的映射在JNA中就是一个function。通过或者function对象,我们可以实现一些非常强大的功能,一起看看吧。
function的定义
先来看下JNA中Function的定义:
public class Function extends Pointer
可以看到Function实际上是一个Pointer,指向的是native function的指针。
那么怎么得到一个Function的实例呢?
我们知道JNA的流程是先进行Library的映射,然后再对Library中的Function进行映射。所以很自然的我们应该可以从Library中得到Function。
我们看一下根据Library name得到function实例的方法定义:
public static Function getFunction(String libraryName, String functionName, int callFlags, String encoding) { return NativeLibrary.getInstance(libraryName).getFunction(functionName, callFlags, encoding); }
这个方法可以接受4个参数,前面两个参数大家应该很熟悉了,第三个参数是callFlags,表示的是函数调用的flags,Function定义了三个callFlags:
public static final int C_CONVENTION = 0; public static final int ALT_CONVENTION = 0x3F; public static final int THROW_LAST_ERROR = 0x40;
其中C_CONVENTION
表示的是C语言类型的方法调用。
ALT_CONVENTION
表示的其他的调用方式。
THROW_LAST_ERROR
表示如果native函数的返回值是非零值的时候,将会抛出一个LastErrorException
。
最后一个参数是encoding
,表示的是字符串的编码方式,实际上指的是 Java unicode和native (const char*) strings 的转换方式。
除了根据Library name获取Function之外,JNA还提供了根据Pointer来获取Function的方法。
public static Function getFunction(Pointer p, int callFlags, String encoding) { return new Function(p, callFlags, encoding); }
这里的Pointer指的是一个执行native
方法的指针,因为Function本身就是继承自Pointer。所以跟Pointer来创建Function的本质就是在Pointer的基础上添加了一些Function特有的属性。
有了Function的定义,更为重要的是如何通过Function来调用对应的方法。跟反射很类似,Function中也有一个invoke方法,通过调用invoke,我们就可以执行对应的Function的功能。
Function
中的invoke
方法有两种,一种是通用的返回对象Object,一种是带有返回值的invoke方法,比如invokeString
,invokePointer
,invokeInt
等。
Function的实际应用
Function
的实际使用和JAVA中的反射有点类似,其工作流程是首先获得要加载的NativeLibrary,然后从该NativeLibrary中找到要调用的Function,最后invoke该Function的某些方法。
C语言中的printf应该是大家最熟悉的native方法了。我们看一下如何使用Function来调用这个方法吧:
可以看到调用的流程非常简洁。如果是用interface Mapping
或者direct Mapping
的形式,我们还需要自定义一个interface或者class,并且在其中定义一个相应的java方法映射。但是如果使用Function的话,这些都不需要了。我们直接可以从NativeLibrary中拿到对应的函数,并最终调用其中的方法。
C语言中的printf的原型如下:
# includeint printf(const char *format, ...);
printf带有返回值的,如果要输出这个返回值,则可以调用Function
中的invokeInt
命令。
我们再来看一个有返回值的调用例子:
NativeLibrary lib = NativeLibrary.getInstance(Platform.C_LIBRARY_NAME); Function f = lib.getFunction("printf"); Object[] args = new Object[Function.MAX_NARGS+1]; // Make sure we don"t break "printf" args[0] = getName(); try { f.invokeInt(args); fail("Arguments should be limited to " + Function.MAX_NARGS); } catch(UnsupportedOperationException e) { // expected }
总结
使用Function可以减少手写Mapping的工作,在某些情况下是非常好用的,但是Function的invoke支持TypeMapper,并不支持FunctionMapper,所以在使用中还是有一些限制。
到此这篇关于java高级用法之JNA中的Function的文章就介绍到这了,更多相关java 中的Function内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
上一篇:C语言 详解字符串基础
X 关闭
X 关闭
- 15G资费不大降!三大运营商谁提供的5G网速最快?中国信通院给出答案
- 2联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 3亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 4现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 5如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 6AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 7转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 8充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 9好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 10名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?