使用JNI呼叫其他.so庫因函式名對不齊引起undefind reference的問題
阿新 • • 發佈:2018-12-09
在實現FrameBuffer快速區域性重新整理庫的過程,我把一部分函式打包成了一個動態連結so庫方便以後其他需要使用FrameBuffer的程式使用。可是在呼叫的時候卻發生了一些奇怪的事情:
我在so庫中編寫了一個void drawPixel(int offset, int color)函式,並且成功編譯成了so庫libdraw_dazzle.so。然後我使用JNI makeFile檔案引入該庫:
#Android.mk LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := draw_dazzle LOCAL_SRC_FILES := libdraw_dazzle.so #LOCAL_EXPORT_C_INCLUDES := lib/include include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := JNIdrawFbLib LOCAL_SRC_FILES := drawFbLib.c LOCAL_LDLIBS += -L$(SYSROOT)/lib -llog LOCAL_CFLAGS := -g LOCAL_SHARED_LIBRARIES := draw_dazzle include $(BUILD_SHARED_LIBRARY)
結果我的JNI檔案在使用ndk-build編譯的時候,在最後連結步驟時,卻報無法找到引用錯誤:
error: undefined reference to 'drawPixel'
clang++.exe: error: linker command failed with exit code 1
就在我百思不得解的時候,一個同事告訴我可以使用Linux命令nm檢視庫的函式名,看看是否函式名發生了什麼改變從而導致了這個問題。結果發現drawPixel函式的名字變成了,看來加了一些標籤,那麼當然引入這個庫函式的時候就會發生失敗了。
於是我把JNI裡面對該函式的應用修改為:
編譯就順利通過了。結果發現這是因為被呼叫庫使用C++編寫,而g++編譯的時候為了方便進行C++函式名多型等的特性實現,必須加一些標記進去才能對函式進行區分所致,有點小麻煩,暫時沒找到可以直接用的辦法。