平面設(shè)計主要做什么的網(wǎng)址seo分析
文章目錄
- 背景
- 過程
- 第一個坑
- 第二個坑
- arm64-v8a 和 armeabi-v7a的區(qū)別
- 實例
- 64位,Android設(shè)備CPU:arm64-v8a
- 32位,Android設(shè)備CPU:armeabi-v7a
- 基本數(shù)據(jù)類型在32位和64位的區(qū)別
- 指針長度在32位和64位的區(qū)別
- 其他可能性
- chatgpt回答參考
背景
使用NDK開發(fā)項目的一個安全庫的時候,踩了一個坑。在這里做一個記錄和總結(jié),避免以后重復踩坑。
需求:開發(fā)安全庫,用作密鑰加密解密,體系位非對稱密鑰體系。
經(jīng)歷:使用的是合作公司提供的C源碼,通過JNI接入C代碼,提供給Java層調(diào)用。
過程
第一個坑
運行的時候Android stduio顯示列鏈接錯誤,懷疑是CMake的問題。新建一個test.c和test.h可以正常運行。發(fā)現(xiàn)是C源碼里面沒有加上:
#ifdef __cplusplus
extern "C"
{
#endif
//c代碼聲明
#ifdef __cplusplus
};
#endif
導致C++鏈接時候和C的符號對不上,鏈接失敗,坑的地方在于編譯器沒有提示這個問題。只能這樣試出來。
第二個坑
前面幾個接口可以正常運行,中間某個接口不能打印,程序不崩潰,只是不能打印。
同樣的代碼在Linux設(shè)備可以正常運行。
debug進去C源碼里面進行代碼review和數(shù)據(jù)觀察分析,發(fā)現(xiàn)里面定義了long 、long long之類的變量。每次在某些循環(huán)操作里面斷開debug。沒能找出原因。
在代碼里面加上數(shù)據(jù)打印,在懷疑的代碼段加上大量的打印日志,觀察數(shù)據(jù)是否越界。數(shù)據(jù)太多,也發(fā)現(xiàn)也沒有越界導致crash。
調(diào)試和思路了半天,沒有思路了。那另外一臺機器來跑一下,bingo!
居然可以正常打印結(jié)果值了。
首先第一件想到的是,可能是cpu架構(gòu)不同導致的。
第一臺機器是arm64-v8a,第二臺測試正常的cpu是armeabi-v7a。
好吧,他們的區(qū)別是一臺是64位,一臺是32位。
懷疑就是不同位數(shù)cpu里面數(shù)據(jù)長度不同導致的。
arm64-v8a 和 armeabi-v7a的區(qū)別
在Android開發(fā)中,arm64-v8a
和 armeabi-v7a
是兩種不同的CPU架構(gòu)。arm64-v8a
適用于64位ARM處理器,而 armeabi-v7a
適用于32位ARM處理器。
先來跑一個實例看看。
實例
void print64And32(){//寫一個代碼32位機器上運行時,輸出sizeof(指針)的結(jié)果是多少,64位機器上運行時,輸出sizeof(指針)的結(jié)果是多少?LOGD("sizeof(int) = %d\n", sizeof(int));LOGD("sizeof(long) = %d\n", sizeof(long));LOGD("sizeof(long long) = %d\n", sizeof(long long));LOGD("sizeof(char) = %d\n", sizeof(char));LOGD("sizeof(float) = %d\n", sizeof(float));LOGD("sizeof(double) = %d\n", sizeof(double));LOGD("sizeof(void *) = %d\n", sizeof(void *));LOGD("sizeof(char *) = %d\n", sizeof(char *));LOGD("sizeof(int *) = %d\n", sizeof(int *));LOGD("sizeof(long *) = %d\n", sizeof(long *));LOGD("sizeof(long long *) = %d\n", sizeof(long long *));LOGD("sizeof(float *) = %d\n", sizeof(float *));LOGD("sizeof(double *) = %d\n", sizeof(double *));}
64位,Android設(shè)備CPU:arm64-v8a
sizeof(int) = 4
sizeof(long) = 8
sizeof(long long) = 8
sizeof(char) = 1
sizeof(float) = 4
sizeof(double) = 8
sizeof(void *) = 8
sizeof(char *) = 8
sizeof(int *) = 8
sizeof(long *) = 8
sizeof(long long *) = 8
sizeof(float *) = 8
sizeof(double *) = 8
32位,Android設(shè)備CPU:armeabi-v7a
sizeof(int) = 4
sizeof(long) = 4
sizeof(long long) = 8
sizeof(char) = 1
sizeof(float) = 4
sizeof(double) = 8
sizeof(void *) = 4
sizeof(char *) = 4
sizeof(int *) = 4
sizeof(long *) = 4
sizeof(long long *) = 4
sizeof(float *) = 4
sizeof(double *) = 4
基本數(shù)據(jù)類型在32位和64位的區(qū)別
從上述實測可以知道,在32位機器上,基本數(shù)據(jù)類型的大小如下:
int
:4字節(jié)long
:4字節(jié)long long
:8字節(jié)char
:1字節(jié)float
:4字節(jié)double
:8字節(jié)
在64位機器上,基本數(shù)據(jù)類型的大小如下:
int
:4字節(jié)long
:8字節(jié)long long
:8字節(jié)char
:1字節(jié)float
:4字節(jié)double
:8字節(jié)
需要注意的是,指針的大小在32位和64位機器上都是相同的,都是8字節(jié)。
指針長度在32位和64位的區(qū)別
32位機器上運行時,輸出sizeof(指針)的結(jié)果是4。
64位機器上運行時,輸出sizeof(指針)的結(jié)果是8。
其他可能性
-
架構(gòu)相關(guān)的問題: 你的應(yīng)用程序可能包含了特定于
arm64-v8a
架構(gòu)的代碼,而這段代碼在armeabi-v7a
上無法正確運行。確保你的應(yīng)用程序中沒有架構(gòu)相關(guān)的問題,并且所有的本地代碼都是通用的。 -
依賴庫問題: 如果你的應(yīng)用程序使用了本地庫(例如C/C++庫),這些庫可能是特定于
arm64-v8a
的。確保你的應(yīng)用程序包含適用于armeabi-v7a
的版本的這些庫。 -
指令集兼容性:
arm64-v8a
使用ARMv8-A指令集,而armeabi-v7a
使用ARMv7-A指令集。確保你的應(yīng)用程序中的本地代碼對目標指令集是兼容的。 -
ABI Filters: 在你的
build.gradle
文件中,可能設(shè)置了 ABI Filters,導致只有arm64-v8a
被打包到 APK 中。檢查你的構(gòu)建配置,確保包含了armeabi-v7a
的支持。
chatgpt回答參考
當你的 C 代碼在 32 位處理器上能夠正常運行,但在 64 位處理器上出現(xiàn)問題時,可能有一些常見的原因:
-
指針大小和類型問題: 64 位處理器上的指針大小為 8 字節(jié),而在 32 位處理器上為 4 字節(jié)。如果你的代碼中存在對指針大小的假設(shè)或者類型轉(zhuǎn)換問題,可能導致在 64 位系統(tǒng)上出現(xiàn)問題。請確保你的代碼對指針操作和類型大小有正確的處理。
-
整數(shù)溢出: 如果你的代碼依賴于特定的整數(shù)大小,可能會在 64 位系統(tǒng)上溢出。在 64 位系統(tǒng)上,
int
類型仍然是 32 位,但long
類型變?yōu)?64 位。確保你的代碼中沒有整數(shù)溢出的問題。 -
對齊問題: 在 64 位系統(tǒng)上,對齊要求可能更加嚴格。如果你的代碼依賴于特定的數(shù)據(jù)結(jié)構(gòu)對齊方式,確保你的結(jié)構(gòu)體或變量的對齊方式是正確的。
-
未初始化變量: 64 位系統(tǒng)上的內(nèi)存布局可能與 32 位系統(tǒng)不同。確保你的代碼中所有的變量都被正確初始化,以防止使用未初始化的內(nèi)存。
-
依賴的庫或第三方代碼: 如果你的代碼依賴于特定的庫或第三方代碼,確保這些庫在 64 位系統(tǒng)上是兼容的。有時,問題可能并不是在你的代碼中,而是在你依賴的庫中。
-
匯編語言代碼: 如果你的代碼包含了匯編語言部分,確保這些匯編語言代碼是對 64 位系統(tǒng)的正確支持。
總體而言,要確保 C 代碼能夠在 64 位處理器上正確運行,需要注意 32 位和 64 位系統(tǒng)之間的差異,并確保代碼中沒有與平臺相關(guān)的假設(shè)。最好的做法是使用編譯器提供的宏來處理不同平臺的區(qū)別,以確保代碼的可移植性。