公司项目需要用到第三方qt插件,由于业务是偏底层的,基本上用不到jar包,因此只能通过jni的方式调用。没学过c++,十多天的摸爬滚打一路过来不容易啊!今天总算跑通了。网上关于jni的资料相关博客有很多,我这里就不重复了,推荐两个博主的文章,我主要把碰到比较困难的问题总结一下。
推荐博客:
https://www.cnblogs.com/roccheung/p/5797415.html
https://blog.youkuaiyun.com/honjane/article/details/53716235
问题1:
首先是参数传递的问题。思路很清晰,java这边定义一个native方法,然后这个方法在c++(qt)那方实现,很容易就能想到参数传递以及返回值是关键,只要搞清楚这两点剩下的逻辑在qt实现就行了。基本传递数据类型比较简单,对象类型通过上面两个系列的文章也能搞定,碰到的第一个问题是复杂对象类型数据的传递。比如类A的参数有int id,B b,C c,即有的字段是对象类型的。甚至再多嵌套几重也是一样的想清楚了还是比较简单的。举个栗子:
//真正实现的时候字段肯定是private,这里只是方便演示(好吧,我摊牌了,少写两行代码-_-..)
//private字段通过get set方法一样能拿到数据。
public class A{
public int id;
//这里如果是human数组或者list也可以,就不搞那么复杂了
public Human human;
public Giraffe giraffe;
//此方法的功能:传入a对象,计算Human 和Giraffe 的身高差
public native static float div(A a);
public A(Human human, Giraffe giraffe) {
this.human = human;
this.giraffe = giraffe;
}
}
class Human{
public String name;
public float tall;
}
class Giraffe{
public String name;
public float tall;
}
将A.java生成头文件com_zone_jni_A.h后看到最主要的地方:
/*
* Class: com_zone_jni_A
* Method: div
* Signature: (Lcom/zone/jni/A;)F
*/
JNIEXPORT jfloat JNICALL Java_com_zone_jni_A_div
(JNIEnv *, jobject, jobject);
新建个Sources文件main.cpp实现这个方法。<