1. 程式人生 > >使用JNI呼叫其他.so庫因函式名對不齊引起undefind reference的問題

使用JNI呼叫其他.so庫因函式名對不齊引起undefind reference的問題

在實現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++函式名多型等的特性實現,必須加一些標記進去才能對函式進行區分所致,有點小麻煩,暫時沒找到可以直接用的辦法。