« 上一篇下一篇 »

坑爹的NDK

今天又被NDK坑了一把,用NDK编译android-4.2.2_r1源代码中一个MediaCodec解码的示例程序,修改好程序后编译,报如下错误:

undefined reference to `android::AMessage::setString(char const*, char const*, int)'

collect2.exe: error: ld returned 1 exit status

顿觉奇怪,这个函数明明有啊,怎么会链接不上,打开源码翻看原型:

struct AMessage : public RefBase {

    ...

    void setString(const char *name, const char *s, ssize_t len = -1);

    ...

}

唯一可疑的地方就是数据类型,这个函数存在于android系统的libstagefright_foundation.so文件中,果断利用IDA打开此文件,发现最终符号如下图:


然后再用IDA打开自己的程序编译后的OBJ文件,发现符号如下图:

果然两个符号不同,一个最后一个字母是l,另外一个是i,果真是数据类型不同导致编译出来的函数符号不同,所以才链接不上。


在android-4.2.2_r1源代码中查询ssize_t的定义为:

typedef long ssize_t;


然后在NDK的4.2.2对应的platforms\android-17中查询ssize_t的定义为:

#ifndef _SSIZE_T_DEFINED_

#define _SSIZE_T_DEFINED_

typedef int  ssize_t;

#endif


android源码中是long类型,而NDK中居然是int类型。知道原因以后就好办了,在自己的代码开头,加入如下代码:

#define _SSIZE_T_DEFINED_

typedef long ssize_t;

然后再重新编译,顺利通过,问题解决。


这已经不是第一次被NDK给坑了,难怪网上对NDK那也是骂声一片,甚至还有大牛搞出来NDK的完全替代品CrystaX NDK,它的网站如下:

https://www.crystax.net/


看样子以后开发真的得用CrystaX NDK了。