Andorid编译so为什么必须要找接口实现?
无论是ndk还是源码环境下编译,都不能只提供头文件就行,都需要由编译器去找到具体实现的so才行,so里面没有实现对应的接口都会报错,如:error: undefined reference to 'SSL_library_init'
我以使用openssl为例,做了两个工程分别测试在ndk下编译和源码环境下编译的区别,发现都一个样。那就是必须要找到libcrypt.so和libssl.so才行。这有悖于我们对于so动态库的认知啊!请有识之士告诉我吧。
试验过程:
eclipse中的工程,用ndk编译so的,mk文件中:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= dingran_sotest_test_JniTest.c LOCAL_MODULE := soTest include $(BUILD_SHARED_LIBRARY)
对应的报错信息是:test_JniTest.c:14: undefined reference to `SSL_library_init'
如果把工程放到源码环境下编译,需要修改mk文件为:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= dingran_sotest_test_JniTest.c LOCAL_MODULE := soTest LOCAL_SHARED_LIBRARIES := \ libutils \ libstlport \ libcrypto \ libssl \ base := $(LOCAL_PATH) LOCAL_C_INCLUDES := \ $(base)/../include \ $(base)/../stbruntime \ include $(base)/../../stlport/libstlport.mk LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog LOCAL_PRELINK_MODULE := false LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY)
由于引用了
libcrypto \ libssl \
所以可以正常编译出来,这两个so都在out/下面的system/lib下。是伴随android的external/openssl/编译出来而存在的,所以我们可以直接用了。如果取消这两个库,那么结果和ndk一样:
error: undefined reference to 'SSL_library_init'
至于用ndk怎么编译使用openssl,那就待我下回做个Demo放放来吧,用的原理是预编译。反正是离不开接口的实现,哎,android真是牛逼,这样有什么好处呢?
提前非要找到实现,这样运行时就安全了?这样岂不是很麻烦。