关于NDK的各种---------------------2014-----------4-------------24-
今天开始搞NDK。。。嗯。。最开始老师给我的代码说是C化了的,于是我就按C的风格来搞
首先大概了解了NDK 和 JNI 的区别,可以说NDK是在JNI上提供了一些封装和工具,能直接生成Android可用的静态或动态链接库,当然还提供了一些JNI的API供我们使用,具体可以看docs/STABLE-APIS.html,里面有提供的API~
然后开始学习NDK的用法,大致是 先在JAVA 端写native 关键字的函数,然后用javah 生成头文件,在JNI文件夹里写定义,最后用NDK生成动态链接库,然后在andorid里用loadlibrary(xxx.so)调用。
下了一个现成的框架,是IBM的一个人写的,刚好也是图像处理,挺对口的
http://www.ibm.com/developerworks/cn/opensource/tutorials/os-androidndk/index.html
按着JNI的语法写了一个自己以后调用的函数
JNIEXPORT void JNICALL JAVA_com_msi_ibm_ndk_xxxx(类名)_xxxx(函数名) 紧接(JNIENV 和 jobject)表示一个 JNI 环境指针和调用类对象实例,是必须有的,更多请参考上面那个链接
然后自己试了一下,返回一个byte[],因为像素的值为0~255,所以一般用unsigned char数组存储,然后传入为一个bitmap对象,用NDK提供的函数
AndroidBitmap_lockPixels(env,bitmap,&pixelpoint)把bitmap的数据指针传递给pixelpoint,
需要注意的是bitmap的数据存储方式,若是一个rpg图,则需要定义一个结构体
typedef struct{
uint8_t r;
uint8_t g;
uint8_t b;
}rgb;
然后把这个指针转换为结构体指针~应该不难理解吧,就像定义一个模具去取数据,前提是你知道数据的存储方式。
取到指针就可以修改了,其他在那个链接里都有
然后是extern 关键字的作用
extern关键字是主要是让自己的C模块可以用到其他C模块已经定义的全局变量或函数。
例如在a.c里
int foo(){
}
那么在b.c里有
extern int foo();
http://blog.csdn.net/david_xtd/article/details/7448313 //这个比较全
表示在其他地方(这里是a.c)里有foo函数的定义,去找一下然后在b.c里用
其实和.h差不多。。。
具体参照http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html
http://blog.csdn.net/yuyantai1234/article/details/7245412
解决了这两个问题就不难理解上面那个IBM用来图像处理的代码了
后来发现程序其实是用C++写的而且用了模版类,template关键字是C里没有的,坑爹啊!
然后考虑了一下,唉,还是把程序改成C++的吧。。
然后就开始查怎么才能让NDK用C++编译器去编译cpp文件然后生成动态链接库
查了半天,妈的连个规范一点的文档都没有
然后网上有人说在Android.mk里加LOCAL_CPP_EXTENSION:=.cpp,,extension的的意思是后缀,这句的意思是把.cpp当成cpp去处理,这不是屁话?
正确的做法
看文档docs/CPLUSPLUS-SUPPORT.html里写了
NDK自带默认的C++运行环境,如果有特别的C++需求,需要在APPLICATION.mk里加
APP_STL:=xxx,xxx表示你想要的环境,然后把.C改成CPP,把JNI部分加上extern "C" {}包围,
然后把(*env)->改成env->,还有一些其他需要改的,例如函数setbyteRegion()里就需要把参数4改成(const jbyte*),要不然传不进去
template好像可以通过链接了,报的是其他问题,请等待进一步的补充