最近客户有需求,需要编译安卓上arm64的EasyClient库。本来想想,很easy的一个事情,结果遇到了坑了,折腾了好久。。。为了这个揪心低级失误,特来写篇博客记录下。
通常在jni中,native层的句柄,一般会用java层的一个整形数值来映射,在接口调用时,把这个整形数据通过参数传递给底层,再转换成句柄。典型的例子就是MediaRecorder,大家可以参考其源码。这在32位系统中是没有任何问题的,但是64位系统,句柄的长度是64位,上层用32位的int就会丢失数据,这样传递给底层时候就会成为一个无效句柄,引来灾难。
于是我第一件事情就是把int改为long,对应的相关接口也改了。但是有一个接口,init,没改过来——这个接口恰好就是用来创建句柄映射的,它通过返回值把句柄传递给上层——依然返回了int。
当我编译ok,运行的时候,发现底层莫名其妙地崩溃。单单对结构体一个变量赋值都会崩溃。导致我也即将崩溃。
Fatal signal 11 (SIGSEGV) at 0x56643280 (code=2)
7、8个小时后,偶然发现init里对句柄的打印和其它地方的打印,值不一样,才发现用来init的返回值为int,导致后续传递给底层的句柄都是无效句柄。。。
问题找到后,改之,就OK了,同32位的一样,视频很快就出来了。