项目的源码在这里:
http://code.google.com/p/flying-on-android/
因为用到了dlopen等函数,所以,编译ToolLibrary时,需要给LOCAL_SHARED_LIBRARIES加上libdl。
调用当前目录的子目录下面的Android.mk时,写法如下:
include $(LOCAL_PATH)/lib/Android.mk
如果像下面这样写的话
include lib/Android.mk
实际搜索目录是/lib/Android.mk
dlsym通过名字来定位方法,所以,方法不能重载。
dlopen也可以传入路径,如:/system/lib/libflying_display.so
编译出来的.so库被安装到/system/lib目录下:
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
如果想安装到/system/lib/hw下面的话,就这样写:
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES和LOCAL_LDLIBS是什么关系?
前者的话,编译时需要检测动态库是否需要重新编译,后者不需要。
在源码中使用libskia.so的话,要这样写:
LOCAL_SHARED_LIBRARIES = libskia
在NDK使用的话,要这样写:
LOCAL_LDLIBS = -lskia
在源码中,LOCAL_LDLIBS适用于HOST SHARED LIBS(不需要检测动态库源文件是否改变),而LOCAL_SHARED_LIBRARIES适用于TARGET SHARED LIBS(需要检测)
在源码中编译flying中的ToolLibrary时,需要链接libdl.so库,有两种写法:
LOCAL_SHARED_LIBRARIES := libdl
LOCAL_LDLIBS += -ldl
第一种可以编译通过,第二种编译失败,说找不到dlopen等的定义。
是因为libdl.so也属于TARGET SHARED LIBS。它的源码位于/bionic/libdl/目录下。
关于host library和target library可以参考这里:
The host library and target library
http://osr507doc.sco.com/en/tools/ShLib_Implement_Host.Target.html
关于LOCAL_PRELINK_MODULE,可以参考这里:
Android编译系统——续
http://blog.csdn.net/a345017062/archive/2011/05/24/6442325.aspx
关于dlopen dlsym dlclose等函数,可以参考这里:
dlopen dlsym dlclose解析
http://blog.csdn.net/yujixi123/archive/2010/07/28/5772117.aspx
只是有一个地方需要注意,如果源码是.cpp文件话,一定要加上
extern "C" {
}
否则的话,会出现dlopen成功,但是用dlsym找不到符号的问题。
因为系统很可能会使用g++编译器来编译.cpp文件,编译出来的符号名不是C风格的,所以就找不到了。
可以参考这里:
gcc与g++测试
http://blog.csdn.net/a345017062/archive/2011/05/31/6457761.aspx
只要在ToolLibrary.cpp文件的开头写一个这样的宏定义:
#define LOG_TAG "ToolLibrary"
那么ToolLibrary.cpp文件中使用LOGW("abc");进行打印时,打印出来的就是这样的LOG了:
W/ToolDisplay( 2176): Hello ToolLibrary!
不要管编译时出现的警告:
warning: this is the location of the previous definition