2012-03-29 68 views
4

我正在創建一個命令行C++測試應用程序(可執行文件),以在我的rooted android設備上運行。未定義的引用錯誤 - rand

可執行文件使用多個預構建的C庫,其中一個使用'rand()'。在鏈接狀態期間,我得到錯誤「未定義的參考'rand'

要檢查路徑設置是否正確,我嘗試了下面的方法,但沒有成功。

第一種方法:我在我的測試源中定義了rand()。

我注意到,我得到多發定義錯誤,第一個定義仿生爲/ libc中/有/ stdlib.h中

方法二:使用蘭特()在我的測試應用

通知我鏈接器不會抱怨這裏未定義的符號

第三條道路:解除封存和歸檔所有的目標文件

發現我仍然收到未定義的引用錯誤。

當使用'rand'的C庫被編譯成使用C測試文件的可執行文件時,看不到所提到的鏈接器錯誤。

我無法修改預建的靜態庫,需要使用我的基於C++的測試應用程序庫。

任何投入將非常受歡迎。

+0

這聽起來像庫希望rand返回'int rand'而不是'unsigned int rand'。如果它是靜態鏈接的,爲什麼要使用'hack'並編譯/鏈接一個測試C文件? – 2012-03-29 14:00:18

+0

rand是一個標準的C模塊,並在創建共享對象或可執行文件時進行鏈接。提供給我的靜態庫使用rand()調用,並沒有包含它的定義。 – Deepak 2012-03-30 05:16:15

+0

我會建議尋找一個符號傾銷。我知道rand()是什麼,我發現你的靜態庫可能是針對與C庫不同的版本編譯的。你可以通過很多方式來清除它(提供你自己的rand,爲C rand提供一個'wrapper'等等......),但你最好的選擇是檢查符號轉儲。我也會指導你http://stackoverflow.com/questions/4768180/rand-implementation – 2012-03-30 07:26:00

回答

1

不夠分置評所以...

如果您在仿生的stdlib.h中看看,你會看到蘭特()被定義爲

靜態直列 INT蘭特(無效){ ...}

即該函數的實際代碼在頭文件中。

這就是爲什麼你的第一種方法會給你一個多重定義的錯誤。

第二種方法由於相同的原因而成功,並且(因爲函數是內聯的)在對象文件中不生成'extern'引用以導致搜索任何庫。

下一步。您的C++代碼將鏈接到libc或libstdC++(您需要檢查)。你的預建靜態庫顯然是針對stdlib.h編譯的,它沒有內聯實現rand()。

您需要在靜態上執行LDD(或readelf)命令,並查看您的平臺上沒有找到它的庫。這個庫很可能與仿生的名稱相同,不會導出rand()符號,因此加載程序無法解析引用。

現在,至於解決這個問題......你至少能夠重建靜態庫,如果不改變它們?你的C測試文件是交叉編譯爲android還是本地?

0

使用'android-ndk32-r10-windows-x86_64.zip',不'android-ndk64-r10-windows-x86_64.zip'

APP_ABI := armeabi armeabi-v7a x86 

3 API是32位。