jna的版本是4.1.0
控制台输出的testJNI()输出的testJNI done不是第一个输出吗?为什么在最后才输出?
我试过在testJNI()和声明double[]之间加了睡眠Thread.sleep(),但是不管是多少秒,testJNI done也是要等到最后才输出,这是什么情况。
你反过来试试看,说不定输出还真能反过来,虽然我没遇到过。
因为for ()
这样写是迭代器,延迟执行的,所以只有等它迭代完,输出了1 2 3,才执行完testJNI
如果要先输出testJNI,你需要先将结果存入数组,然后
for (i = 0; i < arr.length(); i++) arr[i] 这样访问。
在testJNI()前,随意输出一个字符或数字,然后再执行后面的程序,看输出结果就可以判断是什么原因引起的
两个问题,1.jvm类初始化顺序问题。2.内部类与外部类的关系。
我没看到类内部定义接口的实现类是什么,看你描述,实现testDll接口的类,实现的 testJNI方法是输出“testJNI done”字符了。
先说内部类与外部类的关系。
一个内部类,是依附于所附属的外部类的对象的。也就是说,实现TestDll接口的类,是依附于JNA对象的。换句话说,就是每一个JNA对象(不是JNAl类),都包含有一个实现TestDll接口的类。这里是DLL中的class类。
再说类的初始化顺序。
1.先静态域(域包括属性和方法,代码块),后动态域(属性,方法,代码块)。2.先属性,后方法(代码块),构造方法早于普通方法。3.还有重要一点,针对静态域中用到的静态域(不管属性还是方法),会打破静态域范围内出现顺序进行初始化,用到时即初始化(而且只要初始化一次,第二次出现,就不需要再初始化了)。4.如果有父类,则先初始化父类,后初始化子类(跟本问题关系不大)
本题,JNA没有属性,只有一个主方法和一个内部接口。
主方法是静态(static修饰)的,内部接口本质上最终要实现为内部类才能使用,也就是这个内部接口的实现类依附于JNA对象。本题就是instance的类所属JNA对象(不是JNA类)。而且,这个内部类是非静态的(无static修饰)。
当要初始化,首先,寻找静态属性和静态方法。发现没有静态属性,略过。接着寻找静态构造方法,无,略过。按顺序,没有静态代码块,只找到了一个静态方法main方法。此时进行初始化main。
1.main方法中第一行,通过dll,获得一个实现类,并对外暴露接口testJNI.可以把instance看成是TestDLL实现类的一个对象。由于TestDLL接口的实现类是属于外部类的对象的,也就是instance是属于JNA类的对象的,所以,此处需要初始化一个JNA类的对象。但在该处,是静态方法内部,需要先把静态方法中的变量全部初始化结束后才能初始化非静态部分。所以,此处的初始化被放到初始化静态方法main方法之后才进行初始化。而且一定需要初始化,不会不初始化。
因此,先初始化了静态部分中的 dd以及for语句块,然后才初始化非静态的一个JNA对象,这个对象,作用域是main方法,对象中的testJNI在main方法执行的过程中被调用,打印出了 testJNI done。
如果想按照顺序的方式执行,尝试将接口 testDLL定义为 static试试。
1.你可以先在C和Java中打印时,加入时间戳(可适量加入sleep),通过观察时序变化来确定;
2.你在C的Dll中打印输出后,增加语句 fflush(stdout);,强制刷新缓存。(或者尝试用C++的std::cout)