pjsip庫分析

http://blog.chinaunix.net/space.php?uid=287570&do=blog&cuid=728411

如果你對SIP/VoIP技術感興趣,哪希望你不要錯過:),如果你對寫出堪稱優美的Code感興趣,那么你也不可錯過:)這期間我想分析一下一個實際的協議棧的設計到實現的相關技術,算是自己的一個學習經歷記錄.最初選擇這個庫做分析的原因很簡單,文檔齊全:),其它良好的特征則是慢慢發現的:) www.pjsip.org

1.?? ?PJSIP簡介

PJSIP的實現是為了能在嵌入式設備上高效實現SIP/VOIP.其主要特征包括:

?? ?1).極具移植性.(Extremely portable)

?? ??? ?當前可支持平臺包括:

?? ??? ??? ?* Win32/x86 (Win95/98/ME, NT/2000/XP/2003, mingw).

?? ??? ??? ??? ?* arm, WinCE and?Windows Mobile.

?? ??? ??? ??? ?*?Linux/x86, (user mode and as kernel module(!)).

?? ??? ??? ??? ?* Linux/alpha

?? ??? ??? ??? ?* Solaris/ultra.

?? ??? ??? ??? ?* MacOS X/powerpc

?? ??? ??? ??? ?* RTEMS (x86 and powerpc).

?? ??? ?正移植到:

?? ??? ??? ??? ?*?Symbian?OS

??? 2).非常小的足印.(Very small footprint)

?? ??? ?官方宣稱編譯后的庫<150Kb,我在PC上編譯后加上strip后大概173Kb,這對于嵌入式設備,是個好消息:)

??? 3).高性能.(High performance)

?? ??? ?這點我們后面可以看看是否如作者宣稱的:)

??? 4).支持眾多的特征.(Many features)

?? ??? ?這點可以從http://www.pjsip.org/sip_media_features.htm#sip_features看出.

??? 5).充足的SIP文檔.(Extensive SIP documentation)

?? ??? ?這是我最初選擇該庫的原因,當然不是最終的原因,最終的原因是它的code:)

2.?? ?PJSIP的組成.

?? ?其實說是PJSIP不是特別貼切,這個庫實際上是幾個部分組成的.

?? ?1).PJSIP - Open Source SIP Stack[開源的SIP協議棧]

?? ?2).PJMEDIA - Open Source Media Stack[開源的媒體棧]

?? ?3).PJNATH - Open Source NAT Traversal Helper Library[開源的NAT-T輔助庫]

?? ?4).PJLIB-UTIL - Auxiliary Library[輔助工具庫]

?? ?5).PJLIB - Ultra Portable Base Framework Library[基礎框架庫]

?? ?而在最上層庫的目錄分為:(可以使用tree -d -L 1 查看)

?? ?$TOP/build?? ??? ?[包含Makefile]

?? ?$TOP/build.symbian?? ?[針對symbian的Makefile]

??? $TOP/pjlib?? ??? ?[參考上面]

?? ?$TOP/pjlib-util?? ??? ?[參考上面]

?? ?$TOP/pjnath?? ??? ?[參考上面]

??? $TOP/pjmedia?? ??? ?[參考上面]

?? ?$TOP/pjsip?? ??? ?[參考上面]

?? ?$TOP/pjsip-apps

??? $TOP/third_party

?? ?而在每個子目錄,可以看到分為:

?? ?bin?? ??? ??? ??? ??? ?[編譯后產生的二進制文件]

?? ?build?? ??? ??? ??? ??? ?[Makefile]

?? ??? ?build/output

?? ??? ?build/wince-evc4

?? ?docs?? ??? ??? ??? ??? ?[doxygen的文檔,用doxygen docs/doxygen.cfg產生]

?? ?include?? ??? ??? ??? ??? ?[頭文件]

?? ?lib?? ??? ??? ??? ??? ?[編譯后產生的庫]

?? ?src?? ??? ??? ??? ??? ?[源代碼]

3.?? ?PJLIB簡介?
??? 要理解好PJSIP,就不得不先說說PJLIB,PJLIB算的上是這個庫中最基礎的庫,正是這個庫的優美實現,才讓PJSIP變得如此優越。

?? ?PJLIB提供了一系列特征,這是我們下面分析的重點,涉及到:

?? ?1).非動態內存分配[No Dynamic Memory Allocations]

?? ??? ?實現了內存池,獲取內存是從與分配的內存池中獲取,高性能程序多會自己構造內存池,后面我們會解釋該內存池的使用以及基本的原理。根據作者的比較,是常規的 malloc()/free()函數的30倍。

?? ?2).OS抽象[Operating System Abstraction]

?? ??? ?實現OS抽象的根本原因在與可移植性,毋庸置疑:).

?? ??? ?涉及到:

?? ??? ?a).線程[Threads.]

?? ??? ?b).線程本地存儲[Thread Local Storage.]

?? ??? ?c).互斥[Mutexes.]

?? ??? ?d).信號燈[Semaphores.]

?? ??? ?e).原子變量[Atomic Variables.]

?? ??? ?f).臨屆區[Critical sections.]

?? ???? g).鎖對象[Lock Objects.]

?? ??? ?h).事件對象[Event Object.]

?? ??? ?i).時間管理[Time Data Type and Manipulation.]

?? ??? ?j).高解析的時間戳[High Resolution Timestamp.]

?? ??? ?等等,這些我們后面分析代碼時一一看來

?? ?3).低層的網絡相關IO[Low-Level Network I/O]

?? ???? 這涉及到:

?? ???? a).Socket抽象[Socket Abstraction.]

?? ???? b).網絡地址解析[Network Address Resolution.]

?? ???? c).實現針對Socket的select API[Socket select() API.]

?? ?4).時間管理[Timer Management]

?? ??? ?這主要涉及到兩個部分,一個時定時器的管理,還有就是時間解析的精度(舉例說來,就是能精確到哪個時間等級,比如 POSIX sleep(),就只能以秒為單位,而使用select()則可以實現毫秒級別的計時)

?? ?5).各種數據結構[Various Data Structures]

?? ??? ?主要有:

?? ??? ?a).針對字符串的操作[String Operations]

?? ??? ?b).數組輔助[Array helper]

?? ??? ?c).Hash表[Hash Tabl]

?? ??? ?d).鏈表[Linked List]

?? ??? ?e).紅黑平衡樹[Red/Black Balanced Tree]

?? ?6).異常處理[Exception Construct]

?? ??? ?使用的是TRY/CATCH,知道C++/JAVA之類面向對象語言的人看過會宛而一笑:)

?? ?7).LOG機制[Logging Facility]

?? ??? ?很顯然,一個良好的程序,好的LOG機制不可少。這能很方便的讓你去調試程序,對此我是深有體會,任何時候,不要忘記“好的程序,是架構出來的;而能跑的程序,是調試出來的:)”

?? ?8).隨機數以及GUID的產生[Random and GUID Generation]

?? ??? ?GUID指的是"globally unique identifier",只是一個標識而已,比如說你的省份證,算的上是一個GUID,當然,準確說來是“china unique identifier”:). 看了這么多的特征列舉,是不是很完備,的確。總算是初步列舉完了PJLIB的基本特征了,后面我們來說說它的使用與實現:

4.?? ?PJLIB的使用

?? ?有了上述介紹,是不是很想知道這個庫的使用,沒關系,我們慢慢說來:)

?? ?首先是頭文件和編譯出來的庫的位置,這就不必多說了,除非你沒有使用過手動編譯的庫,如果不太了解步驟,google一下,啊:)

?? ?1).為了使用這個庫,需要使用:

?? ?#include <pjlib.h>

?? ?當然,也可以選擇:

?? ?#include <pj/log.h>

??? #include <pj/os.h>

??? 這種分離的方式,不過,簡介其間,還是使用第一種吧:),畢竟,你不需要確認到你所需的函數或者數據結構具體到哪個具體的頭文件:)

??? 2).確保在使用PJLIB之前調用 pj_init()來完成PJLIB庫使用前說必須的一些初始化.

??? 這是一個必不可少的步驟.

??? ~~~~~~~~~~~~~~~~~~~~~~

??? 3).使用PJLIB的一些建議

??? 作者對使用PJLIB的程序提出了一些建議,包括如下 :

?? ??? ?a).不要使用ANSI C[Do NOT Use ANSI C]

?? ??? ?觀點很明確,ANSI C并不會讓程序具有最大的移植性,應該使用PJSIP庫所提供的響應機制來實現你所需要的功能.

?? ??? ?b).使用pj_str_t取代C風格的字符串[Use pj_str_t instead of C Strings]

?? ??? ?原因之一是移植性,之二則是PJLIB內置的pj_str_t相關操作會更快(性能).?? ??? ?

?? ??? ?c).從內存池分配內存[Use Pool for Memory Allocations]

?? ??? ?這很明顯,如果你知道為什么會使用內存池的話(提示一下,性能以及易用性:))

?? ??? ?d).使用PJLIB的LOG機制做文字顯示[Use Logging for Text Display]

?? ??? ?很明顯:)

???? 還有些關于移植的一些問題,不在我們的討論范圍,如果你需要移植到其它平臺或者環境,請參http://www.pjsip.org/pjlib/docs/html/porting_pjlib_pg.htm

5.?? ?PJLIB的使用以及原理

?? ?終于開始提及實現原理以及具體的編碼了:),前面的列舉還真是個瑣碎的事情,還是奔主題來:).

?? ?5.1快速內存池[Fast Memory Pool]

?? ?前面說過,使用內存池的原因在于性能的考慮,原因是C風格的malloc()以及C++風格的new操作在高性能或實時條件下表現并不太好,原因在于性能的瓶頸在于內存碎片問題

?? ?下面列舉其優點與需要主要的問題:

?? ?優點:

?? ?a).不像其它內存池,允許分配不同尺寸的chunks.

?? ?b).快速.

?? ??? ?內存chunks擁有O(1)的復雜度,并且操作僅僅是指針的算術運算,其間不需要使用鎖住任何互斥量.

?? ?c).有效使用內存.

?? ??? ?除了可能因為內存對齊的原因會浪費很少的內存外,內存的使用效率非常高.

?? ?d).可預防內存泄漏.

?? ??? ?在C/C++程序中如果出現內存泄漏問題,其查找過程哪個艱辛,不足為外人道也:(

?? ??? ?[曾經有次用別人的Code,出現了內存泄漏,在開發板上查找N天,又沒工具可在開發板上使用,哪個痛苦,想自殺:(]

?? ??? ?原因很簡單,你的內存都是從內存池中獲取的,就算你沒有釋放你獲取的內存,只要你記得把內存池destroy,那么內存還是會還給系統.

?? ?還有設計帶來的一些其它益處,比如可用性和靈活性:

?? ?e).內存泄漏更容易被跟蹤.

?? ??? ?這是因為你的內存是在指定的內存池中分配的,只要能很快定位到內存池,內存泄漏的偵測就方便多了.

?? ?f).設計上從內存池中獲取內存這一操作是非線程安全的.

?? ??? ?原因是設計者認為內存池被上層對象所擁有,線程安全應該由上層對象去保證,這樣的話,沒有鎖的問題會讓內存分配變得非常的快.

?? ?g).內存池的行為像C++中的new的行為,當內存池獲取內存chunks會拋出PJ_NO_MEMORY_EXCEPTION異常,當然,因為支持異常處理,也可以使用其它方式讓上層程序靈活的定義異常的處理.

?? ?[這是異常處理的基本出發點,但是這有大量的爭論,原因是這改變了程序的正常流程,誰能去保證這種流程是用戶所需要的呢,因此C++中的異常處理飽受爭議,請酌情使用]

?? ?h). 可以在后端使用任何的內存分配器.默認情況下是使用malloc/free管理內存池的塊,但是應用程序也可以指定自己的策略(strategy),例如從一個全局存儲空間分配內存.

?? ?恩,要知道,任何事務都是兩面的(頗為佩服創造出“雙贏”這個詞的語言天才, 不過,文字游戲對于技術人員不能說是件好事情:(),好了,使用時,不要認為這個內存池是哪種"perfect"的技術,要記得"任何設計,都是在各種限制條件中的一個折中,對于'戴著鐐銬的舞蹈',除了'舞蹈',也不要忘記'鐐銬'哦",不要忘了告誡:):

?? ?告誡[Caveats]:

?? ?a).使用合適的大小來初始化內存池.

?? ??? ?使用內存池時,需要指定一個初始內存池大小, 這個值是內存池的初始值,如果你想要高性能,要謹慎選擇這個值哦,太大的化會浪費內存,過小又會讓內存池自身頻繁的去增加內存,顯然這兩種情況都不可取.

?? ?b). 注意,內存池只能增加,而不能被縮小(shrink),因為內存池沒有函數把內存chunks釋放還給系統,這就要去內存池的構造者和使用者明確使用內存.

?? ?恩,基本的原理都差不多了,后面我們來看看如何使用這個內存池.

?? ?5.2內存池的使用[Using Memory Pool]

?? ? 內存池的使用相當的簡單,扳個手指頭就搞定了,如果你看明白了上面的原理和特征:)

?? ? a).創建內存池工廠[Create Pool Factory]

?? ? 上面不是提及內存池的內部分配策略以及異常處理方式么, 其實這就是指定這個的:)

?? ? 當然,不需要你每個內存池都自己取指定策略和異常處理方式,PJLIB已經有了一個默認的實現:Caching Pool Factory,這個內存池工廠的初始化使用函數pj_caching_pool_init()?? ?

?? ? b).創建內存池[Create The Pool]

?? ? 使用pj_pool_create(),其參數分別為內存工廠(Pool Factory),內存池的名字(name),初始時的大小以及增長時的大小.

?? ? c).根據需要分配內存[Allocate Memory as Required]

?? ? 然后,你就可以使用pj_pool_alloc(), pj_pool_calloc(), 或pj_pool_zalloc()從指定的內存池根據需要去獲取內存了:)

?? ? d).Destroy內存池[Destroy the Pool]

?? ? 這實際上是把預分配的內存還給系統?? ?

?? ? e).Destroy內存池工廠[Destroy the Pool Factory]

?? ? 這沒什么好說的.

?? ? 很簡單吧:)

?? ? 作者在文檔中給出了一個例子:

?? ? 如下:

?

  1. #include?<pjlib.h>?
  2. #define?THIS_FILE????"pool_sample.c"?
  3. ?
  4. ???static?void?my_perror(const?char?*title,?pj_status_t?status)?
  5. ???{?
  6. ????????char?errmsg[PJ_ERR_MSG_SIZE];?
  7. ?
  8. ????????pj_strerror(status,?errmsg,?sizeof(errmsg));?
  9. ????????PJ_LOG(1,(THIS_FILE,?"%s:?%s?[status=%d]",?title,?errmsg,?status));?
  10. ???}?
  11. ?
  12. ???static?void?pool_demo_1(pj_pool_factory?*pfactory)?
  13. ???{?
  14. ????????unsigned?i;?
  15. ????????pj_pool_t?*pool;?
  16. ?
  17. ????????//?Must?create?pool?before?we?can?allocate?anything?
  18. ????????pool?=?pj_pool_create(pfactory,??//?the?factory?
  19. ??????????????????????????????"pool1",???//?pool's?name?
  20. ??????????????????????????????4000,??????//?initial?size?
  21. ??????????????????????????????4000,??????//?increment?size?
  22. ??????????????????????????????NULL);?????//?use?default?callback.?
  23. ????????if?(pool?==?NULL)?{?
  24. ????????????my_perror("Error?creating?pool",?PJ_ENOMEM);?
  25. ????????????return;?
  26. ????????}?
  27. ?
  28. ????????//?Demo:?allocate?some?memory?chunks?
  29. ????????for?(i=0;?i<1000;?++i)?{?
  30. ????????????void?*p;?
  31. ?
  32. ????????????p?=?pj_pool_alloc(pool,?(pj_rand()+1)?%?512);?
  33. ?
  34. ????????????//?Do?something?with?p?
  35. ????????????...?
  36. ?
  37. ????????????//?Look!?No?need?to?free?p!!?
  38. ????????}?
  39. ?
  40. ????????//?Done?with?silly?demo,?must?free?pool?to?release?all?memory.?
  41. ????????pj_pool_release(pool);?
  42. ???}?
  43. ?
  44. ???int?main()?
  45. ???{?
  46. ????????pj_caching_pool?cp;?
  47. ????????pj_status_t?status;?
  48. ?
  49. ????????//?Must?init?PJLIB?before?anything?else?
  50. ????????status?=?pj_init();?
  51. ????????if?(status?!=?PJ_SUCCESS)?{?
  52. ????????????my_perror("Error?initializing?PJLIB",?status);?
  53. ????????????return?1;?
  54. ????????}?
  55. ?
  56. ????????//?Create?the?pool?factory,?in?this?case,?a?caching?pool,?
  57. ????????//?using?default?pool?policy.?
  58. ????????pj_caching_pool_init(&cp,?NULL,?1024*1024?);?
  59. ?
  60. ????????//?Do?a?demo?
  61. ????????pool_demo_1(&cp.factory);?
  62. ?
  63. ????????//?Done?with?demos,?destroy?caching?pool?before?exiting?app.?
  64. ????????pj_caching_pool_destroy(&cp);?
  65. ?
  66. ????????return?0;?
  67. ???}?

BTW:如果要實現嵌入式設備上的SIP電話或者其它,PJSIP是我所見的Coding和Design最為優秀的了,就算不是為了實現SIP協議棧,它的Coding方式,以及調試的接口,各種基礎組件的定義,也讓人深刻,可以當作一份優秀的源代碼來閱讀,就像小說一般:) 我就不解釋了:)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/247975.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/247975.shtml
英文地址,請注明出處:http://en.pswp.cn/news/247975.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue — 第二天(v-model和過濾器)

VUE-02-v-model和過濾器 昨日反饋與回顧 代碼倉庫的問題 不要修改你克隆下來的倉庫中任意代碼&#xff0c;否則&#xff0c;下次pull時&#xff0c;可能會報錯&#xff0c;從而得到不到最新的代碼。 如果已經遇到了這個沖突&#xff1a; 解決沖突(git 中解決沖突)把關鍵代碼…

Count

題目鏈接&#xff1a;點這里 題目意思&#xff1a;令f(x)表示<x的正整數中與x互質的數的平均數*2&#xff0c;求sigma(f(i)^k),L<i<R Solution: 首先&#xff0c;我們定義\(S(x)\sum_{gcd(a,x)1}a\)&#xff0c;因為gcd(a,x)1&#xff0c;所以對于任意a&#xff0c;滿…

牛人iOS開發系列--音頻播放、錄音、視頻播放、拍照、視頻錄制

概覽 隨著移動互聯網的發展&#xff0c;如今的手機早已不是打電話、發短信那么簡單了&#xff0c;播放音樂、視頻、錄音、拍照等都是很常用的功能。在iOS中對于多媒體的支持是非常強大的&#xff0c;無論是音視頻播放、錄制&#xff0c;還是對麥克風、攝像頭的操作都提供了多套…

Vue — 第三天(計算屬性和json-server)

計算屬性 使用場景 如果一個結果需要依賴data中的數據&#xff0c;但是需要經過一些邏輯處理&#xff0c;才能得到你想要的數據。此時就可以使用計算屬性。 例如&#xff1a;要對給定的字符串做翻轉處理之后再來顯示。 <div id"app"><!-- 此處邏輯復雜 …

JQuery的ready函數與JS的onload的區別詳解

JQuery的ready函數與JS的onload的區別&#xff1a;1.執行時間window.onload必須等到頁面內包括圖片的所有元素加載完畢后才能執行。$(document).ready()是DOM結構繪制完畢后就執行&#xff0c;不必等到加載完畢。 2.編寫個數不同window.onload不能同時編寫多個&#xff0c;如果…

Vue — 第四天(components組件)

問題導入 下面的代碼是一個折疊面板的效果。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Docu…

iOS開發常用的RGB色值和宏

iOS中RGB常用的色值,同時可將對顏色的設置定義成宏,方便開發應用,如: // name 顏色相關 // 參數格式為&#xff1a;0xFFFFFF #define kColorWithRGB(rgbValue) \ [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16)) / 255.0 \ …

防火墻綜合實驗

防火墻技術綜合實驗 一、實驗目的&#xff1a;本次實驗是將多種訪問控制列表以及防火墻部分的知識做一個匯總 二、實驗內容 A&#xff1a;Established控制列表 拓撲圖 配置步驟 1:配置各端口ip地址&#xff0c;配置登陸密碼 R4: 登陸賬號&#xff1a;ys 密碼&#xff1a;123 2:…

iOS獲取當前設備型號等信息總結 包含iPhone7和iPhone7P

#include <sys/types.h> #include <sys/sysctl.h>//獲得設備型號(NSString *)getCurrentDeviceModel {int mib[2];size_t len;char *machine;mib[0] CTL_HW;mib[1] HW_MACHINE;sysctl(mib, 2, NULL, &len, NULL, 0);machine malloc(len);sysctl(mib, 2, mac…

Vue — 第五天(路由)

前端路由 問題導入 在前面完成的資產管理案例中&#xff0c; 我們是把列表區域和添加表單區域實現在了一個區域。當頁面功能比較復雜時&#xff0c;我們需要它們拆分開來&#xff1a;一個頁面中只顯示一個區域。 一個比較直觀的解決方案是把它們分別做成兩個獨立的網頁文件&…

獲取網絡時間,在不同時間觸發事件

<!DOCTYPE html><html lang"en"><head>   <meta charset"UTF-8">   <title>時間事件</title></head><body></body><script> var int_timenew Date();//使用Date獲取網絡時間;   functi…

iOS獲取手機的IP地址

1.添加這五個庫&#xff08;在聯網的情況下&#xff09; #import <sys/socket.h> #import <sys/sockio.h> #import <sys/ioctl.h> #import <net/if.h> #import <arpa/inet.h>2.寫一個方法 - (NSString *)getDeviceIPIpAddresses {int sockfd soc…

Vue — 第六天(vue-cli-介紹)

vue-cli-介紹 vue-cli是官方提供的開發vue項目的腳手架工具。 腳手架是為了保證各施工過程順利進行而搭設的工作平臺。 在開發過程中&#xff0c;腳手架工具是有用的&#xff0c;開發完成&#xff08;項目上線&#xff09;&#xff0c;它就沒有用了。 vue-cli可以提供基于vue項…

python安裝pyautogui遇到的gbk異常解決

一開始使用pip install pyautogui,報錯,大概信息如下: Collecting pygetwindow (from pyautogui) Using cached https://files.pythonhosted.org/packages/01/ed/56d4a369c6e18f6b239d9ef37b3222ba308bfebf949571b2611ff7d64f1d/PyGetWindow-0.0.4.tar.gz ERROR: Complete …

NSString的各種用法總結(創建、截取、判斷比較、轉化數據類型、拼接、替換、添加、追加、讀取、寫入、刪去、改變)

1、創建字符串1&#xff09;NSSring *str ”adf”;2&#xff09;NSString *str1 [NSString new];NSString *str2 [[NSString alloc] initWithString:”adf”]; &#xff08;等同于1&#xff09;4&#xff09;NSString *str3 [NSString stringWithFormat:”name is %”,”小…

Vue — 第七天(vue-cli-案例)

資料獲取地址&#xff1a; github: https://gitee.com/wang_yu5201314/VUE_vuecli SSH&#xff1a; gitgitee.com:wang_yu5201314/VUE_vuecli.git hero案例-項目介紹 功能介紹&#xff1a; 三個模塊 英雄列表(只做這個)裝備列表技能列表 英雄列表 列表組件刪除功能添加組件編…

postman測試工具

做文件上傳測試的時候可以選擇輸入方式為文件 做文件下載測試的時候&#xff0c;可以選擇 轉載于:https://www.cnblogs.com/thesun/p/10853226.html

webpack — 概述介紹

webpack概述 webpack是一個流行的前端項目構建工具&#xff08;打包工具&#xff09;&#xff0c;可以解決當前web 開發中所面臨的困境。 webpack提供了友好的模塊化支持&#xff0c;以及代碼壓縮混淆、處理js兼容問題、性能優化等強大的功能&#xff0c;從而讓程序員把工作的…

徹底解決iOS項目中 _OBJC_CLASS_$_XXXService, referenced from: 的類似問題

這是大家熟悉的開發過程中可能遇到的問題 這是提交源碼到appStore不支持64位設備的提示 本人在提交項目到appStore時發生的的錯誤&#xff0c;提示必須要支持64的設備&#xff0c;然后自己趕緊進行相關的適應&#xff0c;出現了類似標題的問題&#xff0c;解決方法如下: 1、…

THUPCCTSAPIO2019:Far Away

流水賬~ THUPC nmdwsmduliu&#xff01; THUPC Day -INF~Day -2 大概就是自己做題和每周兩次的考試&#xff0c;lsy和fcw兩個外校的來吊打我們qwqqq THUPC Day -1 Z208 長沙->北京 在車上看gzy/tjj/xzz打擺&#xff1f; THUPC Day 0 從火車站出來做地鐵的時候和tjj做反了可海…