请教关于 android JNI 方法 undefined reference 问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
BigUncleLee
V2EX    Android

请教关于 android JNI 方法 undefined reference 问题

  •  
  •   BigUncleLee 2017-09-19 17:39:57 +08:00 11753 次点击
    这是一个创建于 2945 天前的主题,其中的信息可能已经有所发展或是发生改变。

    工作需要,从三方获取到一个 so 和头文件 (头文件里的函数不是 JNI 标准头)
    写一个工具类封装好 native 方法,再写个 cpp 文件定义好 JNI 标准头
    CMakeLists 文件里定义好 SHARED 的 native 和 IMPORTED 的三方库
    在 cpp 文件里 import 头文件,然后直接调用头文件中定义好的函数
    前面都没有问题
    结果 build 失败了,显示在 cpp 中调用的函数都不存在

    想了想 我写了一个 cpp 类文件,打包出一个 so 文件 是可以正常使用的
    但是使用 cpp 文件 直接定义函数 然后打包出一个 so 文件 就无法正常使用了- - (已经都用 extern "C"包裹了)
    我问了下三方的开发 他们果然是使用 cpp 后缀 但是直接定义的函数

    不知道大家在做 JNI 的过程中有没有遇到这样的情况,是如何解决的?
    谢谢大家:)

    6 条回复    2017-09-20 08:29:04 +08:00
    lrannn
        1
    lrannn  
       2017-09-19 18:05:40 +08:00
    是不是 CMakeLists 中没有链接好第三方动态库?
    BigUncleLee
        2
    BigUncleLee  
    OP
       2017-09-19 18:10:30 +08:00
    @lrannn 链接是没问题的
    诡异的时 我使用 cpp 定义类的方式打出的 so 是可以找到函数的
    用 cpp 定义函数的方式打出 so 其它都不做更改 就找不到了- -
    wshcdr
        3
    wshcdr  
       2017-09-19 18:24:49 +08:00
    关注下这个问题...
    xhcnb
        4
    xhcnb  
       2017-09-19 18:40:47 +08:00
    查看出错的信息, 找不到的符号名称是什么, 再用 ndk 下面的 readelf 或 nm 查看 so 里的符号表, 对比一下
    C 和 C++生成的函数符号是不一样的, 确保编译时头文件和源文件都被正确的处理, 比如 cpp 里函数使用 extern "C", 那么头文件里的声明也必须是 extern "C"
    描述的可能不太清楚, 看一下生成的 so 符号表和报错的信息一下子就明白了
    TonyHoAspire
        5
    TonyHoAspire  
       2017-09-19 18:42:51 +08:00   1
    如果你对 ELF 以及编译链接的过程非常熟悉的话可以这样子做:

    0. gcc 手动 compile 与 link,得到 verbose 信息。确定 link 的时候确实用到了 so 文件( input object ),如果 link 确实将 so 文件作为了 input,那么看下面的 1,否则设置好-L -l 选项
    1. 用 IDA Pro,或者 binutils 工具( readelf,objdump )来查看 so 文件中的 symbols,看看 undefined 的 symbols 在 ELF 文件(你这里是.so 文件)中的的 names 属性( export 的 Global ?还是确实 undefined ),如果确实 undefined 的话那么就是 so 的问题了。但是这种情况少见。
    2. 如果是 names 的问题,那么用 c++-filt 来解析确定原本的 symbol 名字是正确的,将头文件改正确即可,当然你也可以修改 so 文件来完成。

    最后如果是 arm instruction 的话,可能需要注意 CPU 与指令集甚至 fpu 的 tuning 选项。
    RLib
        6
    RLib  
       2017-09-20 08:29:04 +08:00
    你明白 extern "C" 的作用吗?可能是这里的问题
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     6008 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 02:08 PVG 10:08 LAX 19:08 JFK 22:08
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86