2012-10-09 25 views
1

我需要編譯一些c/C++代碼。使用NDK和Cygwin的工具,不止一次我想出了錯誤「undefined reference to」。大多數人都說這是由調用lib文件未包含在源文件中的函數引起的。但是,我對c/C++知之甚少,並且錯誤日誌也給出了模糊信息,所以我不知道哪個文件的哪一行會導致問題,甚至不知道我真的需要哪個lib文件。如何使錯誤日誌更詳細地關於未定義的參考

我的希望是,我找到了一些工具或一些方法來應對這樣的,所以我可以找出錯誤行或獲取有關該錯誤的一些更詳細的問題。

非常感謝。

Android.mk

LOCAL_PATH:= $(call my-dir) 
include $(CLEAR_VARS) 
include ../includeOpenCV.mk 
ifeq ("$(wildcard $(OPENCV_MK_PATH))","") 
#try to load OpenCV.mk from default install location 
include $(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk 
else 
include $(OPENCV_MK_PATH) 
endif 
LOCAL_MODULE:=AvatarSpeak 
LOCAL_SRC_FILES:=AvatarSpeak.cpp 
LOCAL_LDLIBS := -llog 
include $(BUILD_SHARED_LIBRARY) 

$ NDK/NDK-構建V = 1

$ $NDK/ndk-build V=1 
rm -f ./libs/armeabi/lib*.so ./libs/armeabi-v7a/lib*.so ./libs/mips/lib*.so  ./libs/x86/lib*.so 
rm -f ./libs/armeabi/gdbserver ./libs/armeabi-v7a/gdbserver ./libs/mips/gdbserver  ./libs/x86/gdbserver 
rm -f ./libs/armeabi/gdb.setup ./libs/armeabi-v7a/gdb.setup ./libs/mips/gdb.setup  ./libs/x86/gdb.setup 
Gdbserver  : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver 
mkdir -p ./libs/armeabi 
install -p /cygdrive/d/android-ndk-r8b/prebuilt/android-arm/gdbserver/gdbserver ./libs/armeabi/gdbserver 
Gdbsetup  : libs/armeabi/gdb.setup 
mkdir -p ./libs/armeabi 
echo "set solib-search-path ./obj/local/armeabi" > ./libs/armeabi/gdb.setup 
echo "directory D:/android-ndk-r8b/platforms/android-14/arch-arm/usr/include "../../OpenCV-2.3.1/share/OpenCV/../../include/opencv" "../../OpenCV- 2.3.1/share/OpenCV/../../include" D:/android-ndk-r8b/sources/cxx-stl/gnu-  libstdc++/4.6/include D:/android-ndk-r8b/sources/cxx-stl/gnu- libstdc++/4.6/libs/armeabi/include jni" >> ./libs/armeabi/gdb.setup 
SharedLibrary : libAvatarSpeak.so 
/cygdrive/d/android-ndk-r8b/toolchains/arm-linux-androideabi-  4.6/prebuilt/windows/bin/arm-linux-androideabi-g++ -Wl,-soname,libAvatarSpeak.so -shared  --sysroot=D:/android-ndk-r8b/platforms/android-14/arch-arm ./obj/local/armeabi/objs-  debug/AvatarSpeak/com_huawei_avatar_AvatarSpeak.o ./obj/local/armeabi/libopencv_contrib.a  ./obj/local/armeabi/libopencv_calib3d.a ./obj/local/armeabi/libopencv_objdetect.a  ./obj/local/armeabi/libopencv_features2d.a ./obj/local/armeabi/libopencv_video.a  ./obj/local/armeabi/libopencv_imgproc.a ./obj/local/armeabi/libopencv_highgui.a   ./obj/local/armeabi/libopencv_ml.a ./obj/local/armeabi/libopencv_legacy.a  ./obj/local/armeabi/libopencv_flann.a ./obj/local/armeabi/libopencv_core.a  ./obj/local/armeabi/libopencv_androidcamera.a ./obj/local/armeabi/liblibjpeg.a  ./obj/local/armeabi/liblibpng.a ./obj/local/armeabi/liblibtiff.a  ./obj/local/armeabi/liblibjasper.a ./obj/local/armeabi/libzlib.a  ./obj/local/armeabi/libgnustl_static.a -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-  z,relro -Wl,-z,now -LD:/android-ndk-r8b/platforms/android-14/arch-arm/usr/lib -llog -lc -   lm -o obj/local/armeabi/libAvatarSpeak.so 
./obj/local/armeabi/objs-debug/AvatarSpeak/AvatarSpeak.o: In function  `Java_com_hachi_avatar_AvatarSpeak_speak': 
D:\eclipse_workspace\TestSo/jni/com_hachi_avatar_AvatarSpeak.cpp:52: undefined  reference to `Fap2Avi2D(char const*, char const*, char const*, char const*, char const*, int)' 
collect2: ld returned 1 exit status 
/cygdrive/d/android-ndk-r8b/build/core/build-binary.mk:378: recipe for target  `obj/local/armeabi/libAvatarSpeak.so' failed 
make: *** [obj/local/armeabi/libAvatarSpeak.so] Error 1 

AvatarSpeak.cpp

if (fImage != NULL && fPot != NULL) { 

    bool sucavi = Fap2Avi2D(str3, str5, str4, str1, str2, -1); 
    LOGI("sucess and exit!"); 
} else { 
    LOGI("unsucess and exit!"); 
} 

Animation2D_new.h(頭文件,其中定義方法Fap2Avi2D

#ifndef ANIMATION_2D_NEW_H_ 
#define ANIMATION_2D_NEW_H_ 

#include <vector> 
#include <string> 
#include "public.h" 
#include "FaceExpressionEditor.h" 
//#define __declspec(dllexport) 

bool Fap2Avi2D(const char *fap_file,const char *avi_file,const char *wav_file, const char* image_file,const char *pot_file=NULL,int codec_type=-1); 
... 

回答

1

更多的,往往不是「未定義的引用」指的是您的構建配置錯誤。例如,Android.mk文件中的意外換行符可能會導致make工具爲您的項目選擇錯誤的鏈接命令。

一般錯誤消息包括將其尋找這個參考丟失功能或全局變量,並且所述模塊(文件)的名稱。如果該名稱不言自明的,你可以經常發現這名字在你的源代碼,然後跟蹤回給你使用外部庫之一,因爲它很可能是在一些頭(聲明。 h.hpp)文件包含在您的源文件中。

這是不太可能你無意中使用,你必須下載一些外部庫,因爲通常這種錯誤表現自己更早的時候,編譯器無法找到所需的包括(頭)文件。

Android本地項目顯示「未定義引用」錯誤的一個特殊情況是項目使用非官方Android API(例如, OpenMax的/ stagefreight。在這種情況下,頭文件可以在Android源代碼樹中找到,但鏈接階段所需的編譯庫不存在。通常的解決方法是從開發設備中提取二進制文件,例如

adb pull /system/lib/libstagefreight.so . 

不管怎麼說,這往往有助於與V上運行ndk-build = 1看到什麼構建命令被執行。

+0

嗨,亞歷克斯,在閱讀您的文章後,仍然無法找到處理我的問題的線索,所以我發佈了一些我的代碼,希望您能給我一些更詳細的解決方案。非常感謝。 – stardust

+1

那麼,文件'Animation2D_new.h'用於聲明** Fap2Avi2D()函數,但不會[** define **](http://www.cprogramming.com/declare_vs_define.html)它。你可能有相應的'Animation2D_new.cpp'文件;你應該明確地將它添加到'LOCAL_SRC_FILES' –

+1

再次感謝Alex,問題解決了。 – stardust

0

沒有找到「失蹤庫」沒有通用的方法。這是您作爲程序員(和Google用戶)的技能必須被激活的地方。

第一步是始終確定函數屬於哪個庫。使用Google總是一個不錯的選擇。

當你知道這一點,你需要找出如果庫安裝在系統上。如果沒有,就這樣做。

然後你需要添加這個依賴到你的構建系統。這是如何完成的取決於所使用的環境和工具。谷歌再次是你最好的選擇。