文章編號:10630時間:2024-09-28人氣:
在 C 編程中,小字符串優化是一種技術,它可以顯著提升應用程序的性能和效率,特別是對于大量處理小字符串的應用程序。
小字符串通常是指長度在 16 個字節或更短的字符串。
小字符串優化技術主要通過以下方式實現:
strcmp
和
strlen
)可以提高性能,因為這些函數針對小字符串進行了優化。
以下示例展示了如何應用小字符串優化:
// 使用寄存器變量存儲小字符串register char str = "Hello";// 使用局部變量存儲小字符串void my_function() {char str[] = "World";}// 使用內置字符串函數比較小字符串if (strcmp("
1 提高子菜單速度位 置:HKEY_CURRENT_USER\Control Panel\Desktop鍵值名:Menushowdelay雙擊鍵值Menushowdelay后,彈出該鍵值的編輯窗口,在文本輸入框內輸入“0”后,再單擊“確定”按鈕即可。 注意在系統默認的菜單彈出效果下,不易感覺到菜單彈出速度的提高;這時,請在桌面上單擊“屬性”命令,彈出“顯示 屬性”窗口,然后在“效果”標簽下將“動畫顯示菜單和工具提示”下的“淡入淡出效果”改為“滾動效果”。 2 去掉“關閉系統”位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer鍵值名:NoClose取 值:1為隱藏、0為顯示3 自動刷新窗口內容位 置:HKEY_LOCAL_MACHINE\System\Currentcontrolset\Control\Update鍵值名:UpdateMode取 值:0、1若“UpdateMode”鍵值為0,則設置為自動刷新,若“UpdateMode”鍵值為1,則設置為手工刷新;這等于在資源管理器窗口內按“F5”鍵或者在“查看”菜單中選擇“刷新”命令。 4 去掉“設置”一 位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer鍵值名:NoSetFolders取 值:1為隱藏、0為顯示二 位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer鍵值名:NoSetTaskbar取 值:1為隱藏、0為顯示5 去掉升級位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer鍵值名:NoCommonGroups取 值:1為隱藏、0為顯示6 去掉“文檔”位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer鍵值名:NoRecentDocsMenu取 值:1為隱藏、0為顯示7 自動清除“文檔”位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer鍵值名:ClearRecentDocsOnExit取 值:1為自動清除、0為不自動清除8 去掉“查找”位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer鍵值名:NoFind取 值:1為隱藏、0為顯示9 鎖定“文檔”位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer鍵值名:NoRecentDocsHistory取 值:1為鎖定、0為不鎖定10 去掉“運行”位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer鍵值名:NoRun取 值:1為隱藏、0為顯示11 搜索“自啟動”程序位 置:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run在注冊表內,我們可以查詢系統啟動后加載了哪些程序。 單擊注冊表內的目錄樹,這里最重要的是“裝載源”,從“軟件環境”、“啟動程序”顯示的結果看,絕大多數“自啟動”程序都是通過注冊表加載的,即“裝載源”顯示為“Registry (Machine Run)”的程序。 12 去掉“注銷”位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer鍵值名:NoLogOff取 值:1為隱藏、0為顯示13 縮短“新建”選項當你用鼠標右鍵點擊資源管理器空白處,并選取新建菜單時,會彈出建立多種程序文件的菜單,但是里面有一些你可能并不常用,比如現在我要去除掉菜單中的“Wave Sound”項目,來縮短菜單。 打開注冊表,請選擇查看下的搜索項,然后輸入“shellnew”,并選擇“全字匹配”選項;在HKEY_LOCAL_MACHINE與HKEY_LOCAL_ROOT下進行查找,找到后將該其下面的shellnew子鍵刪除掉即可。 14 清除配色方案位 置:HKEY_CURRENT_USER\Control Panel\Appearance\Schemes首先請找到該子鍵,在窗口的右邊會出現系統自帶的各種配色方案,將你認為無用的配色方案刪除掉,一般只保留“Windows默認”一項。 然后再打開“控制面板”窗口中的“顯示”,然后在“顯示 屬性”窗口中單擊“外觀”標簽,在“窗口配色方案”下拉列表中進行查看。 15 修改桌面圖標例如,我們修改Windows桌面上“回收站”的名字及圖標,可執行如下操作步驟。 位 置:HKEY_CLASSES_ROOT\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}先打開注冊表編輯器;然后根據上面提供的位置找到該主鍵,雙擊窗口右邊的“回收站”,彈出字符串編輯器, 然后在文本輸入框內,將“回收站”改為“垃圾筒”, 重新啟動機器后,桌面上的回收站就變成了垃圾筒,但圖標依舊!單擊{645FF040-5081-101B-9F08-00AA002F954E}前面的“+”,則展開這個主鍵,在它下面還有一個子鍵DefaultIcon。 然后單擊此子鍵,在右窗格中的“數據”欄下將出現三個圖標文件名,分別為“$#@60;未命名$ 2;”、“Full”(滿)、“Empty”(空)的回收站圖標,這三個圖標包含在動態鏈接庫文件里面,圖標資源所在的序號分別是31、31、32, 其數據格式是“C:\Windows\System\,31”等(調用動態鏈接庫中的圖標資源,采用這種格式就可以啦!)。 如果您想把它改成自己的圖標,則只要將此數據改為自己圖標或者動態鏈接庫即可,例如使用圖標文件為“C:\Windows\”,這樣再重新啟動機器就可以看到垃圾筒的圖標被改變了。 利用同樣的方法可以修改桌面上其它的圖標和文字。 16 刪除“系統”當你想刪除桌面上的“回收站”、“Internet Explorer”等圖標時,會發現它們不能用一般的方法刪除。 這時還可以通過修改注冊表來辦到。 位 置:HKEY_LOCAL_ MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace在該分支下面有多個子鍵,這些子鍵將對應桌面上的“系統”圖標,在窗口右邊你就可以看到。 刪除不需要的圖標,即對應的鍵值;重新啟動后,會看到桌面上的一些圖標不見啦!17 隱藏桌面位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion \Policies\Explorer鍵值名:NoDesktop取 值:0、1這種隱藏桌面圖標的方法與簡單地在“顯示 屬性”窗口內,使用“Active desktop”下的隱藏圖標的方法不一樣。 這里的隱藏除了將圖標隱藏外,連整個桌面都一并隱藏了起來,并且同時禁止了在桌面上點擊鼠標右鍵功能。 18 去掉“網上鄰居”位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer鍵值名:NoNetHood取 值:1為隱藏、0為顯示19 關閉系統版本號位 置:HKEY_CURRENT_USER\Control Panel\desktop鍵值名:PaintDesktopVersion取 值:0為隱藏、1為顯示說 明:它能把你的Windows的版本號在桌面的右下角顯示出來,如果你使用的是測試版, 那么就可以將桌面右下角的文字去掉。 20 隱藏指定驅動器位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer鍵值名:NoDrives取 值:需要說明一下,在這里使用的是2的N次方來代表一個驅動器名稱,而非尋常的A、B、C、D……,下面就給出各驅動器名與2的N次方的對應關系,以方便讀者:A: 1, B: 2,C: 4, D: 8, E: 16, F: 32, G: 64,H: 128, I: 256,J: 512,K: 1024, L: 2048, M: 4096, N: 8192,O: , P: , ,R: ,S: ,T: , U: , V: , W,X: , Y: , Z: 按照上面的取值規則,如果你要隱藏A、B、C三個驅動器,輸入7即可,因為7=1+2+4,如果你要隱藏所有驅動器,輸入。 21 修改“回收站”位 置:HKEY_CLASSES_ROOT\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\ShellFolder鍵值名:Attributes取 值:40 01 00 20、70 01 00 20說 明:缺省情況下是40 01 00 20,把它改為70 01 00 20后,就可以把桌面上的“回收站”象資源管理器內的文件一樣,能任意地更名或者刪除了。 22 修改桌面位 置:HKEY_CURRENT_USER\ControlPanel\desktop說 明:打開注冊表編輯器,然后打開該分支。 在此分支右窗格內可以看到一些項目,現介紹幾個如下:HungAppTimeout:這是指一個應用程序出錯時試圖等待響應的時間,值為毫秒,缺省值為5000毫秒(即5秒),可以減少為3000毫秒,以加快系統的響應能力。 MenuShowDelay:這是指“開始”菜單中當鼠標指向一個具有下級 菜單的菜單項時等待出現下級菜單的延遲時間,單位也是毫秒,可以設成100,即等待0.1秒就會出現(前面已經提到過)。 ScreenSaveActive:這是現在屏幕保護功能是否可用,值為0或1,0即為不用屏幕保護功能,1為可用,但必須你已經使用了屏幕保護功能。 ScreenSaveTimeOut:這是指屏幕保護的延時,值類型為一個數值。 單位是秒,最小值是60秒,但必須你已經使用了屏幕保護功能;如果你將數值改為1,那么每停頓1秒鐘,便會啟動屏幕保護。 WaitToKillAppTimeout:這是指當按下 Crtl+Alt+Del后以后,出現“關閉程序”對話框,出現提示“結束任務”、“等待”時選擇“等待”的等待時間,單位是毫秒,默認值是。 可以減少等待時間。 23 定制按鈕顏色盡管Windows在外觀中可以定義多種窗口顯示方案,但要定義某一個部位的顏色,如將黑色的按鈕字體改變為其它的顏色, 它就無能為力啦!通過修改注冊表能很容易實現。 在注冊表內找到HKEY_CURRENT_USER\Control Panel\Colors的子鍵,然后將窗口右邊的“Bottontext”鍵值由原來的“0 0 0”改為“255 0 0”(代表紅色)。 24 漢字后加空格位 置:HKEY_CURRENT_USERS\Software\Microsoft\Windows\CurrentVersion鍵值名:插空格取 值:0不插入空格、1插入空格25 活用Enter鍵位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVer n鍵值名: 取 值:0保留原功能,輸入法不處理、1等同于Esc鍵,用于清除當前外碼輸入狀態說 明:當取值為1時,如果有候選窗口,會自動隱藏輸入窗口,清除所有外碼,但不隱藏外碼輸入窗口。 當無候選窗口,清除外碼,并隱藏外碼輸入窗口。 26 活用Space鍵位 置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion鍵值名: 取 值:0指明這是作為結束外碼輸入的標志鍵,這種設置適合于形碼、1指明這是作為候選選擇鍵,這種設置適合于音碼。 27 系統時間格式 位 置:HKEY_CURRENT_USER\ControlPanel\International鍵值名:sTimeFormat取 值:H:mm:ss、HHmm不等說 明:在通常情況下,Windows在任務欄中使用“23:12”的時間格式來顯示時間, 但是您可以通過修改注冊表編輯器來更改此時間格式。 28 更改登錄背景位 置:HKEY_USERS\\Control Panel\Desktop鍵值名:Wallpaper取 值:目標背景圖文件路徑29 修改注冊碼位 置:HKEY_LOCALMACHINE\Software\Microsoft\Windows\CurrentVersion鍵值名:ProductId取 值:任意字符30 禁止自動運行在通常情況下,絕大多數在Windows啟動時自動運行的應用程序有如下兩種設置辦法:在“啟動”程序組中添加快捷方式 如果使用的是這種方法。 則我們只需將它們的快捷方式從 “啟動”程序組中刪除即可達到禁止它們自動運行的目的。 修改Windows的注冊表數據庫如果您使用過一些諸如CD播放機等的用戶都知道,在使用這些軟件時,都將在任務欄右邊 將出現一個圖標,這有時會帶來不便。 其實,這些軟件的自啟動程序的注冊項放在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run分支中。 您只要到此分支中找出對應的自啟動程序即可,另外,在“Run”主鍵下還可能有“SysExplr”子鍵。 如果有該子鍵,可以將其中的內容清空,同樣也能取消Windows啟動時自啟動的程序。 那么反過來,我們怎樣在注冊表內添加自啟動程序呢?先找到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run主鍵,然后在它的窗口右邊建立一 個名為“SysExplorer”的鍵值名,并將其值設為“”,退出注冊表編輯器,注銷用戶后重新啟動計算機,系統將自動運行資源管理器。 另外Windows還提供了一次性的自啟動功能。 緊跟在“Run”主鍵后面有一個“RunOnce”和“RunOnceEx”子鍵,你可以在這兩個子鍵內設置新的鍵值,讓系統自動運行一次某個程序,即僅在下一次啟動Windows時才有效。 31 軟件顯示亂碼 解決的方法是在注冊表內找到HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\fontassoc\Associated CharSet位置,將窗口右邊內的“SYMBOL(02)” 鍵值(這是系統的機內碼)改為“NO”即可。 32 刪除軟件的殘骸每一個Windows操作系統的的使用者可能都有這樣的經歷,由于種種原因直接在硬盤中刪除了某個文件夾,或者是在“添加/刪除程序”里面對一些軟件進行反安裝。 但是有些程序卻還有注冊信息留在注冊表內,當你再次從“添加/刪除程序”中卸載該程序時,老是提示“試圖刪除XXXXXX時出錯,放棄卸載”,從而導致了卸載程序錯誤。 當機器中安裝大量的軟件后隨著時間的后移,就在系統的注冊表中就形成了垃圾,影響了機器的運行速度。 下面介紹徹底清除這些垃圾的方法。 用注冊表編輯器來清除注冊表中關于卸載應用程序的相關鍵值數據HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall位置,一般的軟件在注冊表內的反安裝子鍵里有“DisplayName”、“UninstallString”這兩個鍵值,第一個顯示的是軟件的名稱、第二個 顯示的是反安裝的一些信息。 雙擊第二個鍵值后,便會明白反安裝是怎么回事,反安裝實際上是你所安裝的軟件自帶有一個反安裝程序,在安裝該軟件時,它會自己記錄一些安裝信息存放文件中,卸載時用這個反安裝程序再帶上文件的參數即可。 另外,有些軟件反安裝時使用的是系統提供的反安裝程序。 再如,許多應用軟件在卸載之后仍會在注冊表文件內留下一些無用信息。 比較集中的地方在HKEY_LOCAL_MACHINE\Software、HKEY_CURRENT_USER\Software和HKEY_USERS\ \Software。 這幾項里面的內容基本上一致,在其中一處作查找刪除就行了。 比較常用到的方法是進入HKEY_LOCAL_MACHINE\Software分支中,然后重點查找那些已經確信被安全卸載了的軟件的殘留信息,在確認無誤后刪除。 33 恢復CD Key如果你不小心將Windows的CDKey丟失了,擔心在以后需要安裝系統時會遇到什么麻煩。 我該如何才能找回它呢?您可以從NT的注冊表中找到這個CDKey。 打開注冊表,然后再找到“HKEY_LOCAL_MACHINE\SOFTWARE\Microso WindowsNT\CurrentVersion”位置,在右側的ProductId鍵值中,就包含了CDKey的信息,另外,如果您所使用的NT是OEM版本,則有可能整個ProductId的串值就是CDKey!34 加入登錄信息因為加入這樣的功能需要修改NT的注冊表,所以請您小心并做好備份。 首先在注冊表中的找到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon子鍵,然后在窗口右邊找到“LegalNoticeCaption”和“LegalNoticeText”兩個鍵值。 如果沒有, 請添加這兩個鍵值。 然后在這兩個鍵值內分別輸入“這是我的服務器”、“歡迎光臨!”。 關閉注冊表,重啟機器,這次您就看到在登錄窗口之前,將會出現一個新的窗口,包含上面您所輸入的這兩條信息。 35 防范非法入侵介紹如何防止本地用戶非法入侵 Windows NT 系統的文章已經并不少見,但如何防范遠程用戶呢?當然,一般的做法是,可以在用戶撥號進入系統(或通過局域網進入系統)時限制其對文件的訪問權限,以達到保護文件的目的。 但畢竟這種安全級別不夠高,如何能將這些用戶鎖在系統的門外,以達到絕對安全的目的呢?NT為驅動器和系統目錄創建默認共享的目的,是為了使系統管理員、備份程序和其他授權用戶及服務性工作能順利訪問其他個人用戶的文件。 當其他用戶訪問您的系統時這些共享對象并不顯現出來。 但是任何一個遠程 用戶只要知道這些共享對象的確切名稱,并且有訪問權的話,他就可以與這些共享對象建立連接。 令人遺憾的是,NT系統的安全機制非常脆弱。 雖然SecurityPack5的出臺為老用戶提高到管理員水平而提供了一些補漏措施,并且還 有一些NT的安全檢查方法,但仍然還會有其他漏洞存在。 所以如果您的計算機在局域網上,或者是通過Modem連接 上網的,那么可通過取消這些組件的共享來保護數據。 為了達到此目的,打開NT的注冊表編輯器。 在注冊表編輯 器中,將當前目錄定位在HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\lanmanagerServer\parameters,如果沒有AutoShareWks鍵值名,那么請你新建立一個;然后再雙擊它并輸入“3D0”,最后單 “確定”按鈕、關閉注冊表編輯器,然后重新啟動計算機。 36 ICQ中有“漏洞”ICQ是由以色列一家叫Mirabilis的公司出品的網絡軟件,其作用是為Internet上的用戶提供實時的信息傳遞服務。 有了它,你就可以同千里之外的朋友交流信息,還可以在對方不在線的情況下“呼叫” 他(她)上線,難怪廣大網友都親切地叫它“網絡尋呼機”。 但是,你是否知道在ICQ for Windows版本中 有一個“漏洞”。 ICQ在Windows注冊表中有一個鍵值被稱為“Auto Update”(自動更新)。 如果該鍵值被設 置成“Yes”,那么每一次登錄到服務器的時候,就會將你的計算機中一些重要信息發送到登錄的服務器上。 這些信息包括:你正在使用的操作系統類型、版本、序列號、用戶登記名稱、公司名稱、所使用的瀏覽器版本等等。 這些重要信息的發送可能會被黑客或某些別有心的人所利用,給你帶來不必要的麻煩。 為了避免此問題的發生可采用修改注冊表關掉ICQ的“自動更新”功能。 首先在注冊表內找到 HKEY_CURRENT_USER\Software\Mirabilis\ICQ\DefaultPrefs位置,并在窗口右邊找到“Auto Update”鍵值; 將“Auto Update”鍵值由“Yes”修改為“No”即可。 為了你系統的穩定性,在進行修改時請注意要在關閉ICQ 應用程序的情況下進行修改。 修改完畢后,請重新啟動計算機。 37 增加執行文件路徑如果需要運行的程序不在指定的目錄中,則DOS系統一般采用在自動批處理文件中設置路徑的方法來達到自動尋找此程序的目的;在Windows中則可以更秘密地增加程序路徑,而不是通過設置自動批處理的方式,這就需要通過修改注冊表來實現上述目的。 比如要為“C:\ProgramFiles\pdoc\”文件增加路徑。 先打開注冊表,然后找到HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\AppPATHs的位置,在窗口右邊新建一個名為“”的主鍵,選擇該主鍵,將其默認值設為“C:\ProgramFiles\pdoc\”;再新建名為“Path”的主鍵,將其設為“C:\ProgramFiles\pdoc”。 這樣就可以通過在“運行”命令行中鍵入“” 或“pdoc”來運行該程序了。 另外你還可以為已經存在的程序設置新的主鍵,比如可以為MicrosoftWord 97添加名稱為“”的主鍵。 假設Word 97安裝在“C:\ProgramFiles\MicrosoftOffice\Office\”目錄中,則其操作為:打開注冊表,在“我的電腦”文件夾中依次選擇“HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\AppPaths”,新建名稱為“”主鍵,選擇該主鍵,將其默認值設為“C:\ProgramFiles\MicrosoftOffice\Office\”即可,建立執行目錄的方法與上例一樣。 38 更改系統安裝目錄如果使用光盤安裝Windows,當添加新的硬件時,系統配置驅動程序時會提醒需要在光驅中插入Win 98光盤,而且每次都 要這樣做,的確太麻煩了。 您可以將Win 98安裝盤中的所有“*”文件都拷貝到硬盤的某個目錄下,比如“D:\Backup\PWin98”,然后運行注冊表編輯器,在“我的電腦”文件夾中依次選擇“HKEY_LOCAL_MACHINE”、“Software”、“Microsoft”、“Windows”、“CurrentVersion”、“Setup”,將“SourcePath”主鍵的值改為“D:\Backup\PWin98\”,重新啟動計算機即可。 如果網絡上有一個文件服務器,假定Win98安裝盤備份在“D:\Backup\PWin98\”目錄中,文件服務器的機器名為“MMX233”,D盤共 享名為“DiskD”,則將“SourcePath”主鍵值改為“\\MMX233\DiskD\Backup\PWin98\”,注銷用戶或重新啟動Windows即可。 39 去掉IE內的分級審查口令首先找到在注冊表的HKEY_LOCAL_MACHINE\Software\Microsoft\Windows \Currentversion\Policies\Ratings位置,這里保存的是IE下“Internet屬性”對話框的“內容”選項頁中的“分級審查”中的口令,該口令是經過加密的,在下圖中你可以看到記錄該口令的有兩個鍵值,而二進制的“key”鍵值則是加過密的,去掉口令的方法即是將子鍵下的這兩個鍵值刪除,如果沒有口令,這個子鍵無鍵值。 下次進入IE,你就可以安全地進入分級審查,并且可以直接跳過輸入“舊密碼”,直接加入密碼即可.40 設置中文Windows內的系統語言如果你安裝了一個英文游戲,并且不支持中文,例如QUAKE。 就可以將中文Windows內的漢字按照英文一樣來處理。 比如每個漢字都被當成了兩個字符來處理,刪掉一個漢字也需要按兩下刪除鍵,而且每到行末,就會出現漢字丟掉一半的奇怪現象。 如果遇到這樣的情況,千萬別著急重新安裝Windwos,你還可以先試一試下面的方法。 首先在注冊找到HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\Nls\Locale的位置,將原來的“”改為默認的“”(系統默認使用的語言系統).41 更改IE標題欄中的文字首先在注冊表中找到下面的位置HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main,然后再新建一個字符串值,將其命名為Window Title(注意兩個詞中間有一個空格).42 如何刪除多余的DLL文件在WIN98的System子目錄下存有大量的DLL文件,這些文件可能被系統或應用程序共享。 但是由于經常安裝和卸載軟件,就會在System目錄下留下一些DLL垃圾文件。 它們不但占用了硬盤空間,而且還降低系統的運行速度。 刪除它們的步驟如下:1.運行“REGEDIT”, 打開注冊表編輯器。 2.打開HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\SharedDLLs分支。 這里SharedDLLs子鍵記錄的就是有關程序共享的DLL信息,每個DLL文件的鍵值說明它已被幾個應用程序共享。 如果是二進制鍵值為“00 00 00 00”,則表明不被任何程序共享。 (另外“0x (1)”是十六進制表示法)3.System目錄中刪除對應的文件。 43 去掉桌面快捷方式的小箭頭在一些程序的安裝過程中,會自動在桌面上創建該程序的快捷方式,方便了我們的使用。 但是那個小箭頭不太好看。 我們可以利用修改注冊表來去掉它。 首先要注意此快捷方式是什么類型的,一般說來以居多,也有一些是(指向MS-DOS程序的快捷方式)。 具體步驟如下:1.運行注冊表編輯器,打開HKEY_CLASSES_ROOT\lnkfile分支。 2.在lnkfile子鍵下面找到一個名為“IsShortcut”的鍵值,它表示在桌面的快捷方式圖標上將出現一個小箭頭。 右鍵單擊“IsShortcut”,然后從彈出的菜單中選擇“刪除”,將該鍵值刪除。 3.關閉注冊表編輯器,重新啟動Win98,就可發現快捷方式圖標上已經沒有小箭頭了。 同理,對指向MS-DOS程序的快捷方式(即)圖標上的小箭頭,則除了是打開HKEY_CLASSES_ROOT\piffile分支外,其余同上。
……如果是輸入一行字符串的話,沒必要定義999個字節的字符串,浪費空間,其余的就是你不能邊轉換便輸出嗎?那樣可以省掉一次對于鏈表的訪問,暫時就這些想法,希望有幫助
一、Debug 和 Release 編譯方式的本質區別 Debug 通常稱為調試版本,它包含調試信息,并且不作任何優化,便于程序員調試程序。 Release 稱為發布版本,它往往是進行了各種優化,使得程序在代碼大小和運行速度上都是最優的,以便用戶很好地使用。 Debug 和 Release 的真正秘密,在于一組編譯選項。 下面列出了分別針對二者的選項(當然除此之外還有其他一些,如/Fd /Fo,但區別并不重要,通常他們也不會引起 Release 版錯誤,在此不討論)Debug 版本: /MDd /MLd 或 /MTd 使用 Debug runtime library(調試版本的運行時刻函數庫) /Od 關閉優化開關 /D _DEBUG 相當于 #define _DEBUG,打開編譯調試代碼開關(主要針對 assert函數) /ZI 創建 Edit and continue(編輯繼續)數據庫,這樣在調試過 程中如果修改了源代碼不需重新編譯 /GZ 可以幫助捕獲內存錯誤 /Gm 打開最小化重鏈接開關,減少鏈接時間 Release 版本: /MD /ML 或 /MT使用發布版本的運行時刻函數庫 /O1 或 /O2優化開關,使程序最小或最快 /D NDEBUG 關閉條件編譯調試代碼開關(即不編譯assert函數) /GF 合并重復的字符串,并將字符串常量放到只讀內存,防止 被修改 實際上,Debug 和 Release 并沒有本質的界限,他們只是一組編譯選項的集合,編譯器只是按照預定的選項行動。 事實上,我們甚至可以修改這些選項,從而得到優化過的調試版本或是帶跟蹤語句的發布版本。 二、哪些情況下 Release 版會出錯 有了上面的介紹,我們再來逐個對照這些選項看看 Release 版錯誤是怎樣產生的 1. Runtime Library:鏈接哪種運行時刻函數庫通常只對程序的性能產生影響。 調試版本的 Runtime Library 包含了調試信息,并采用了一些保護機制以幫助發現錯誤,因此性能不如發布版本。 編譯器提供的 Runtime Library 通常很穩定,不會造成 Release 版錯誤;倒是由于 Debug 的 Runtime Library 加強了對錯誤的檢測,如堆內存分配,有時會出現 Debug 有錯但 Release 正常的現象。 應當指出的是,如果 Debug 有錯,即使 Release 正常,程序肯定是有 Bug 的,只不過可能是 Release 版的某次運行沒有表現出來而已。 2. 優化:這是造成錯誤的主要原因,因為關閉優化時源程序基本上是直接翻譯的,而打開優化后編譯器會作出一系列假設。 這類錯誤主要有以下幾種: (1) 幀指針(Frame Pointer)省略(簡稱 FPO ):在函數調用過程中,所有調用信息(返回地址、參數)以及自動變量都是放在棧中的。 若函數的聲明與實現不同(參數、返回值、調用方式),就會產生錯誤————但 Debug 方式下,棧的訪問通過 EBP 寄存器保存的地址實現,如果沒有發生數組越界之類的錯誤(或是越界“不多”),函數通常能正常執行;Release 方式下,優化會省略 EBP 棧基址指針,這樣通過一個全局指針訪問棧就會造成返回地址錯誤是程序崩潰。 C++ 的強類型特性能檢查出大多數這樣的錯誤,但如果用了強制類型轉換,就不行了。 你可以在 Release 版本中強制加入 /Oy- 編譯選項來關掉幀指針省略,以確定是否此類錯誤。 此類錯誤通常有: ● MFC 消息響應函數書寫錯誤。 正確的應為afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam);ON_MESSAGE 宏包含強制類型轉換。 防止這種錯誤的方法之一是重定義 ON_MESSAGE 宏,把下列代碼加到 stdafx.h 中(在#include afxwin.h之后),函數原形錯誤時編譯會報錯#undef ON_MESSAGE#define ON_MESSAGE(message, memberFxn) \{ message, 0, 0, 0, AfxSig_lwl, \(AFX_PMSG)(AFX_PMSGW)(static_cast< LRESULT (AFX_MSG_CALL \CWnd::*)(WPARAM, LPARAM) > (&memberFxn) },(2) volatile 型變量:volatile 告訴編譯器該變量可能被程序之外的未知方式修改(如系統、其他進程和線程)。 優化程序為了使程序性能提高,常把一些變量放在寄存器中(類似于 register 關鍵字),而其他進程只能對該變量所在的內存進行修改,而寄存器中的值沒變。 如果你的程序是多線程的,或者你發現某個變量的值與預期的不符而你確信已正確的設置了,則很可能遇到這樣的問題。 這種錯誤有時會表現為程序在最快優化出錯而最小優化正常。 把你認為可疑的變量加上 volatile 試試。 (3) 變量優化:優化程序會根據變量的使用情況優化變量。 例如,函數中有一個未被使用的變量,在 Debug 版中它有可能掩蓋一個數組越界,而在 Release 版中,這個變量很可能被優化調,此時數組越界會破壞棧中有用的數據。 當然,實際的情況會比這復雜得多。 與此有關的錯誤有: ● 非法訪問,包括數組越界、指針錯誤等。 例如 void fn(void) { int i; i = 1; int a[4]; { int j; j = 1; } a[-1] = 1;//當然錯誤不會這么明顯,例如下標是變量 a[4] = 1; } j 雖然在數組越界時已出了作用域,但其空間并未收回,因而 i 和 j 就會掩蓋越界。 而 Release 版由于 i、j 并未其很大作用可能會被優化掉,從而使棧被破壞。 3. _DEBUG 與 NDEBUG :當定義了 _DEBUG 時,assert() 函數會被編譯,而 NDEBUG 時不被編譯。 除此之外,VC++中還有一系列斷言宏。 這包括: ANSI C 斷言 void assert(int expression );C Runtime Lib 斷言_ASSERT( booleanExpression );_ASSERTE( booleanExpression );MFC 斷言ASSERT( booleanExpression );VERIFY( booleanExpression );ASSERT_VALID( pObject );ASSERT_KINDOF( classname, pobject );ATL 斷言ATLASSERT( booleanExpression );此外,TRACE() 宏的編譯也受 _DEBUG 控制。 所有這些斷言都只在 Debug版中才被編譯,而在 Release 版中被忽略。 唯一的例外是 VERIFY() 。 事實上,這些宏都是調用了 assert() 函數,只不過附加了一些與庫有關的調試代碼。 如果你在這些宏中加入了任何程序代碼,而不只是布爾表達式(例如賦值、能改變變量值的函數調用 等),那么 Release 版都不會執行這些操作,從而造成錯誤。 初學者很容易犯這類錯誤,查找的方法也很簡單,因為這些宏都已在上面列出,只要利用 VC++ 的 Find in Files 功能在工程所有文件中找到用這些宏的地方再一一檢查即可。 另外,有些高手可能還會加入 #ifdef _DEBUG 之類的條件編譯,也要注意一下。 順便值得一提的是 VERIFY() 宏,這個宏允許你將程序代碼放在布爾表達式里。 這個宏通常用來檢查 Windows API 的返回值。 有些人可能為這個原因而濫用 VERIFY() ,事實上這是危險的,因為 VERIFY() 違反了斷言的思想,不能使程序代碼和調試代碼完全分離,最終可能會帶來很多麻煩。 因此,專家們建議盡量少用這個宏。 4. /GZ 選項:這個選項會做以下這些事 (1) 初始化內存和變量。 包括用 0xCC 初始化所有自動變量,0xCD ( Cleared Data ) 初始化堆中分配的內存(即動態分配的內存,例如 new ),0xDD ( Dead Data ) 填充已被釋放的堆內存(例如 delete ),0xFD( deFencde Data ) 初始化受保護的內存(debug 版在動態分配內存的前后加入保護內存以防止越界訪問),其中括號中的詞是微軟建議的助記詞。 這樣做的好處是這些值都很大,作為指針是不可能的(而且 32 位系統中指針很少是奇數值,在有些系統中奇數的指針會產生運行時錯誤),作為數值也很少遇到,而且這些值也很容易辨認,因此這很有利于在 Debug 版中發現 Release 版才會遇到的錯誤。 要特別注意的是,很多人認為編譯器會用 0 來初始化變量,這是錯誤的(而且這樣很不利于查找錯誤)。 (2) 通過函數指針調用函數時,會通過檢查棧指針驗證函數調用的匹配性。 (防止原形不匹配)(3) 函數返回前檢查棧指針,確認未被修改。 (防止越界訪問和原形不匹配,與第二項合在一起可大致模擬幀指針省略 FPO )通常 /GZ 選項會造成 Debug 版出錯而 Release 版正常的現象,因為 Release 版中未初始化的變量是隨機的,這有可能使指針指向一個有效地址而掩蓋了非法訪問。 除此之外,/Gm /GF 等選項造成錯誤的情況比較少,而且他們的效果顯而易見,比較容易發現。 三、怎樣“調試” Release 版的程序 遇到 Debug 成功但 Release 失敗,顯然是一件很沮喪的事,而且往往無從下手。 如果你看了以上的分析,結合錯誤的具體表現,很快找出了錯誤,固然很好。 但如果一時找不出,以下給出了一些在這種情況下的策略。 1. 前面已經提過,Debug 和 Release 只是一組編譯選項的差別,實際上并沒有什么定義能區分二者。 我們可以修改 Release 版的編譯選項來縮小錯誤范圍。 如上所述,可以把 Release 的選項逐個改為與之相對的 Debug 選項,如 /MD 改為 /MDd、/O1 改為 /Od,或運行時間優化改為程序大小優化。 注意,一次只改一個選項,看改哪個選項時錯誤消失,再對應該選項相關的錯誤,針對性地查找。 這些選項在 Project\Settings... 中都可以直接通過列表選取,通常不要手動修改。 由于以上的分析已相當全面,這個方法是最有效的。 2. 在編程過程中就要時常注意測試 Release 版本,以免最后代碼太多,時間又很緊。 3. 在 Debug 版中使用 /W4 警告級別,這樣可以從編譯器獲得最大限度的錯誤信息,比如 if( i =0 )就會引起 /W4 警告。 不要忽略這些警告,通常這是你程序中的 Bug 引起的。 但有時 /W4 會帶來很多冗余信息,如 未使用的函數參數 警告,而很多消息處理函數都會忽略某些參數。 我們可以用#progma warning(disable: 4702) //禁止//...#progma warning(default: 4702) //重新允許來暫時禁止某個警告,或使用#progma warning(push, 3) //設置警告級別為 /W3//...#progma warning(pop) //重設為 /W4來暫時改變警告級別,有時你可以只在認為可疑的那一部分代碼使用 /W4。 4.你也可以像 Debug 一樣調試你的 Release 版,只要加入調試符號。 在 Project/Settings... 中,選中 Settings for Win32 Release,選中 C/C++ 標簽,Category 選 General,Debug Info 選 Program Database。 再在 Link 標簽 Project options最后加上 /OPT:REF (引號不要輸)。 這樣調試器就能使用 pdb 文件中的調試符號。 但調試時你會發現斷點很難設置,變量也很難找到——這些都被優化過了。 不過令人慶幸的是,Call Stack 窗口仍然工作正常,即使幀指針被優化,棧信息(特別是返回地址)仍然能找到。 這對定位錯誤很有幫助。
不懂移動端開發,也可以貢獻移動端代碼。
無限增強FinClip小程序安全運行沙箱FinClip小程序安全運行沙箱,以SDK的方式供App開發者嵌入,讓自己的App秒變能運行小程序的超級App。 在這里,“App”還不僅僅是指iOS或者Android的應用,宿主可以強大至配備多核CPU和較多內存的PC,也可以是運算能力比較有限的嵌入式設備(embeddeddevices),例如一個帶觸摸屏的RaspberryPI。
宿主硬件環境和軟件環境都各有不同,需要暴露給小程序利用的功能不一樣;此外,不同的商業環境下,應用所集成的原生能力(例如地圖、支付、加密、音視頻、甚至AR/XR等)也不同。 FinClip支持開發者自定義各種API接口,注入至FinClipSDK中,從而以JavaScript的方式供小程序開發者調用。
通過這種方式,任何小程序理論上可利用所在宿主環境的任何技術能力,而不僅受限于FinClipSDK所提供的標準接口。
官方支持的自定義接口擴展方式當前FinClip官方支持的自定義接口,需要用所在宿主環境的原生技術實現,例如在iOS上需要用Objective-C或Swift開發,在Android上則是采用Java/Kotlin等。 這個做法就需要起碼兩個平臺的工程師分別開發-當然過去以來這也不是問題,任何手機端App都不得不維持兩隊人馬搞兩個版本。 但是當你有更多類型的終端要支持的時候,就很麻煩了。
正如在《FinClip小程序+Rust》這個系列所提到,對于純邏輯類、算法類的功能例如音視頻編碼的處理、加解密等等,完全沒有人機交互的部分,采用一個跨平臺的通用語言來實現,更加便利。 但是我們又都不想去折騰C的代碼,Rust是一個很好的選擇。 作為一種新興的、內存安全、線程安全的語言,Rust可跨平臺編譯,高性能、體積小,尤其適合于設備端的編程,包括在低算力、低功耗、低內存的IoT設備上開發Heapless代碼;并且,Rust已經是Android官方支持的系統語言。
那么,FinClip能否支持開發者用Rust提供對其安全運行沙箱的自定義擴展呢?
先看一下FinClip環境下的技能分工與協同回答上述問題前,在這里我們先想象一下,假如在一個端到端的應用軟件生產鏈路上,以FinClip技術為各環節的“粘合劑”,一個新型的技術小組的角色(技能)組成是怎樣的:
iOS/Android/其他終端的“宿主”開發工程師:負責宿主“殼”應用的開發,以及FinClipSDK集成。需要懂ObjC/Swift、Java/Kotlin、乃至Electron/Qt/C++,視乎所要支持的目標操作系統
FinClip小程序開發工程師:負責各種業務功能的前端開發,懂HTML/JavaScript以及一些前端框架即可
FinClipSDKExtension開發工程師:負責實現一些通用的邏輯算法、底層的基礎設施,供各目標終端的“宿主”應用集成。需要掌握Rust編程
DevOps工程師:如果打算自行運行維護自己的FinClip小程序中心、管理自己的小程序開發者和開發生態,那么就需要工程師去部署運行FinClip服務器端
這是一條起碼的“流水線”,各個崗位用不同的語言技能,分工越清晰越好,哪怕這些事情都是同一個人“包打天下”了,也需要自己明確在不同角色下做不同的事,有助于梳理出合理的架構,在一個端到端的技術鏈路上,界定好每一個環節的功能范疇。
Gluecode和生態FinClip這門技術,單純從軟件工程角度看,它扮演的是gluecode(粘合劑)的角色,把一個涉及多種語言、多類技術的軟件系統粘合起來。 Gluecode往往是最繁瑣、也最容易出錯的地方,把這個層面的技術解決好了,能大大釋放開發者的生產力和創造力。 相當于流水線搭建好了,每個環節都可以獨立潤滑、豐富、加強。 而且每個環節都變得更加專業,甚至形成自己的零部件“供應鏈”。
例如,把HTML/JavaScript部分的技術,和設備端原生技術對接好,就引入了大量的可以專注于小程序開發的工程師提供豐富的應用場景;把設備端原生技術中跨設備通用的邏輯解耦出來成為可插拔的“插件”,又可以進一步促生僅聚焦這一部分工作的人,產出豐富、高品質的插件。 只要標準化,就有機會形成生態。
提供端到端的應用解決方案,變成是“集大成”,在技術鏈路各環節的“供應鏈”中,選取自己需要的零部件,去組裝自己的應用。
插件開發者:用Rust實現FinClipSDK的“插件”正如FinClip小程序的開發者無需懂得任何iOS/ObjC/Swift、Android/Java/Kotlin的技能知識,僅憑對HTML/JavaScript的掌握即可開發出有用的應用一樣,FinClipSDKExtension的開發者,最好也無需了解太多操作系統平臺的編程知識,甚至無需跟ObjC、Java打交道,即可開發出自己的擴展。
我們在技術是可以做到的。 按以下的步驟-注意下述內容都發生在Rust這側,對ObjC/Java空間的代碼開發要求為零。
準備構建一個靜態庫所需的環境用cargo創建一個lib類型的項目,例如
cargo?new?--lib?myplugin然后修訂一下所生成的:
[package]name?=?mypluginversion?=?0.1.0edition?=?2021[lib]name?=?myplugin#?this?is?needed?to?build?for?iOS?and?-type?=?[staticlib,?lib][dependencies]serde_json?=?1.0.81??#?建議使用這個crate實現json對象序列化#?其他你準備封裝或者依賴的crate定義準備注入至FinClip的API在src/,開始定義和封裝你計劃提供給原生宿主應用開發者注入至其FinClipSDK的函數。
首先,定義一個新的類型:
type?FinClipCall?=?fn(&String)?->?String;這個類型名字請命名為FinClipCall,且這個類型所表示的函數簽名,必須是:
fn(&String)?->?String它實際上是一個函數指針,它能夠指向這樣的函數,例如:
fn?invoke(param:?&String)?->?String?{...}注意這個類型的函數,期望的輸入參數是一個合法的JSON字符串,返回的也必須是一個合法的JSON字符串。 因為FinClip的自定義API,統一用JSON作為入參和出參,便于小程序側JavaScript代碼的處理。 所以在上文推薦引入serde_json這個crate,幫助做一些JSON相關的數據轉換。
其次,開始實現你的函數實現,例如:
fn?api_drinker(input:?&String)?->?String?{????//?先處理一下入參,把進來的字符串檢測為合法JSON對象,????//?再用serde_json把它轉化為某個類型的參數對象,供后續使用????println!(invoked?with?parameter?{},?input);????//中間的邏輯算法從略,這里應該是你自己的算法,產生的結果對象,可以????//用serde_json進行Json?serialization????let?john?=?json!({????????name:?john?doe,????????phones:?????});????_string()}fn?api_whisky(input:?&String)?->?String?{????//?先處理一下入參,把進來的字符串檢測為合法JSON對象,????//?再用serde_json把它轉化為某個類型的參數對象,供后續使用????println!(invoked?with?parameter?{},?input);????//中間的邏輯算法從略,這里應該是你自己的算法,產生的結果對象,可以????//用serde_json進行Json?serialization????let?brands?=?json!({????????whisky:?{????????????jack:?daniel,????????????johny:?walker,????????????henry:?Mckenna,????????????suntory:?toki????????}????});????_string()}以上以此類推,按類似的簽名來實現你的API。
文字命名你的API名稱并造冊登記“花名”FinClip小程序側,調用自定義API的辦法,是通過API的名字。 例如你把一個API接口命名為abc,那么這個接口被注入到FinClipSDK后,它在JavaScript側的調用,就是(...)。
在此,你需要給每一個自定義函數一個文本命名,并映射它們的關系,這確實有點像代碼編譯器里面的virtualtable。這里,是我們開發的這個myplugin項目中另一個需要注意一下的地方:
pub?unsafe?extern?C?fn?myplugin_register_apis()?->?*mut?HashMap這個函數做了什么事情呢?雖然只有幾行代碼,有必要解釋一下:
首先,我們初始化了一個HashMap,這個HashMap的Key和Value的類型,分別是String和之前我們自定義的函數指針類型FinClipCall
其次,開始造“花名冊”,也就是直接粗暴的窮舉所有要輸出的函數,把它們塞到HashMap,完成造冊
最后,是比較“技巧性”的地方,就是如何把這個HashMap對象返回出去。 記得我們的這些函數,最終必須暴露給iOS、Android等平臺上的宿主應用,以便于這些應用的開發者,把這些函數注入到FinClipSDK,所以這里是你的Rust代碼和你的合作伙伴的ObjC或者Java/JNI代碼的臨界點。 此處我們用了一個辦法,就是把HashMap這個只存在于Rust側的collections類型(就像Java里的collectionclasses只存在于Java一樣),包裝在一個類似C++的smartpointer這樣的Box里,返回這一整個數據結構在內存里的地址
至此,我們的工作基本上完成90%,是不是很簡單?
把提供“花名冊”的函數暴露給其他語言使用到這一步為止,我們都是在Rust世界中折騰。 但是最終這些成果必須被外界發現和使用。 最后異步,就是把“花名冊”送到異構語言的世界中,我們需要利用RustFFI(ForeignFunctionInterface)去讓Rust編譯器編譯上述代碼時,生成C風格的代碼庫,所以對上述函數還要做一點補充:
#[no_mangle]pub?unsafe?extern?C?fn?myext_register_apis()?->?*mut?HashMapno_mangle告訴Rust編譯器,編譯時不要混淆或改變myplugin_register_api()這個函數名字,否則ObjC或者Java/JNI側就無法知道用什么名字調用了。
注意上述函數的聲明里,有unsafe和externC的標識,extern好理解,就是標識這個函數是供異構語言以C函數調用的方式使用,unsafe涉及Rust關于什么才是內存安全、線程安全的規則或者說思想,詳情讀者可自行了解。 在此,主要是我們用到了Box::into_raw這個函數,即我們把一個只在Rust里面才能解析的數據結構,通過一個原始指針把它丟到C側了,相當于這一片內存被異構語言下的代碼“持有”,其內存安全不再受Rust的監控和保障,所以是不安全的。
這里有一個問題,就是:既然Rust側的HashMap無法被C側解析,把這玩意兒的原始指針丟過去有什么用呢?有用,因為它實際上相當于一個不透明指針,是一個由宿主應用側“持有”的handle,當宿主需要調用Rust的函數時,把這個handle傳回來就是了。
有去有回,記得防止內存泄漏在RustFFI,每一次產生的into_raw操作,最終都必須有一次對應的from_raw操作。 前者把一片Rust管理的內存的控制權轉移出去了,后者是外部的異構語言下的代碼必須把該內存的控制權還給Rust,否則內存泄漏就發生了。 所以,最后我們還需要增加一個函數,供異構語言在使用完上面的東西后,記得通知Rust回收:
#[no_mangle]pub?unsafe?extern?C?fn?myext_release(ptr:?*mut?HashMap注意,調用這個函數是宿主應用開發者的責任,所以必須在你的plugin的使用說明文檔中向他們強調。 這個比較丑陋但似乎沒有什么好辦法,跨語言的調用總是有一些小不便。
Re-cap:用Rust開發一個FinClipSDK擴展的步驟實際上是非常簡單和自由的,沒有什么特殊庫或者協議需要去繼承實現,就是“徒手”寫一個Rustlib,只要它包含以下要素:
準備提供給FinClip小程序調用的函數,以JSON字符串為入參和出參。 函數遵循fn(&String)->String的簽名。 這些函數多少個都行,叫什么名字也無妨,自由選擇
給上面這些函數造一個“花名冊”,花名冊的數據結構必須是以HashMap去存儲“名字”->“函數指針”的映射關系,其中“名字”是你打算讓外面的世界知道和使用的函數名(字符串),函數指針則是指向上述函數簽名的類型
產生“花名冊”的函數,需要使用RustFFI,也就是標記no_mangle,以及聲明為unsafe。 “花名冊”的數據結構(HashMap),包在一個不透明指針(opaquepointer)里,丟出去給異構語言代碼(也就是準備使用這個plugin的宿主)持有備用。 這個返回“花名冊”的函數,名字叫什么也無法,你只需要在自己的說明文檔里注明(說明文檔你總得有吧?)
提供一個釋放“花名冊”數據結構內存的函數,同樣的,函數名字隨意,告訴宿主開發者是什么即可
交付物是一個靜態庫正如《FinClip小程序+Rust》這個系列里所介紹過,Rust代碼需要進行跨平臺編譯,構建出aarch64-apple-ios、x86_64-apple-ios以及Android相關的目標架構下的二進制庫。例如生成適合在iossimulator和ios設備上運行的universallibrary:
cbindgen?src/?-l?c?>??lipo?--release最終你交付給宿主應用開發者的內容應該包括:
一個libmyplugin.a文件、一個myplugin.h的頭文件
一個使用說明,包括:
如何獲得你所提供的API的花名錄,例如你提供了一個函數myplugin_register_apis
如何通知你釋放花名錄內存,例如你提供了一個函數myplugin_release
你的API花名錄中,每一個API的“花名”,以及該API期望的JSON入參,返回的JSON出參
至此,作為一個Rust開發者提供FinClipSDKExtension的使命完成。 再次明確,myplugin的頭文件名字、創建花名錄數據結構和釋放花名錄內存的函數名字,都是開發者自由決定。
App開發者:如何使用Rust的插件接下來,就輪到宿主應用的開發者怎么使用了。 宿主應用,就是運行在iOS、Android或者其他設備端的應用軟件,它嵌入了FinClipSDK從而獲得運行小程序能力。
編寫代碼僅需加三行集成FinClipSDK詳見官網,《FinClip小程序+Rust》也有介紹,不在此贅述。以下以iOSApp的集成上述myplugin為例,在AppDelegate.m增加三行代碼(下面有注解的三行):
[package]name?=?mypluginversion?=?0.1.0edition?=?2021[lib]name?=?myplugin#?this?is?needed?to?build?for?iOS?and?-type?=?[staticlib,?lib][dependencies]serde_json?=?1.0.81??#?建議使用這個crate實現json對象序列化#?其他你準備封裝或者依賴的crate0上面的代碼,AppDelegate.m,在用xcode創建ObjC項目時自動生成,我們在這里初始化了FinClipSDK(詳情見官網,或《FinClip小程序+Rust》系列。在此基礎上,再安裝myplugin,代碼非常簡單:
引用myplugin.h
調用FinClipExt的installFor方法,入參為初始化的FinClipSDKhandle,以及myplugin的API“花名錄”對象(由myplugin_register_apis產生)
在宿主應用的生命周期中,找合適的階段(例如應用退出)釋放“花名錄”內存(由myplugin_release提供)
這里的FinClipExt,負責了把RustAPI轉換成ObjC方法再注入到FinClipSDK中。
編譯構建需要鏈接靜態庫myplugin這個庫,從上面我們已經可以看到,沒有使用任何與FinClip直接相關的特殊的庫,唯一的約束,就是兩個規范:
自定義一個叫FinClipCall的函數指針類型,函數簽名必須是fn(&String)->String
提供一個函數,能生成你計劃提供給FinClip小程序開發者使用的自定義API的“花名錄”,它的數據結構,必須是HashMap
僅此而已。 那么這個庫是怎么被注入到FinClipSDK并能被小程序調用的呢?魔術在于,宿主App的開發者,在其項目中引入一個叫libfincliprust.a的靜態庫(這個庫目前尚不是FinClip官方支持的標準工具,只是我個人的項目,且目前僅提供iOS版本。 有興趣的朋友可以去優化,歡迎提供Android的版本,源代碼在GitHub上,由ObjC和Rust代碼組成)。 作為使用者,無需關注其中的實現,只要下載這個靜態庫,編譯構建App的時候指定依賴與鏈接它即可。
最后,當然也必須把所要安裝的myplugin的靜態庫,libmyplugin.a,引入項目,一同構建。
作為宿主應用開發者,引入一個叫myplugin的FinClipSDKExtension供FinClip小程序開發者調用的使命,也完成了。
小程序開發者:如何調用Rust接口上述myplugin的“花名錄”里,有兩個暴露給小程序的API,分別是api_drinker和api_whisky。 這兩個用Rust寫出來的、以JSON字符串為入參和出參的函數,經過libfincliprust.a的一些“魔術”操作,被轉換成ObjC的method,并被動態注入到FinClipSDK中。 要使用這些API,FinClip小程序開發者需要在自己的小程序項目根目錄下編寫一個:
[package]name?=?mypluginversion?=?0.1.0edition?=?2021[lib]name?=?myplugin#?this?is?needed?to?build?for?iOS?and?-type?=?[staticlib,?lib][dependencies]serde_json?=?1.0.81??#?建議使用這個crate實現json對象序列化#?其他你準備封裝或者依賴的crate1此后,在JavaScript中對這些API的調用,只需要通過ft對象即可進行,例如_drinker。
總結在一個現代的軟件項目中,多語言混合編程是難以避免的-不同的語言在端到端技術鏈路上適合于解決不同環節的問題,但是也難免導致集成、融合的麻煩,往往是影響開發效率、引起諸多麻煩的。 例如跨語言的轉接,涉及API接口的產生和數據結構在異構語言中反反復復的“翻譯”,寫gluecode非常繁瑣。 FinClip更平滑的解決了前端的異構技術對接問題,在本文中,進一步介紹了一個較為“透明”的方法,讓完全不熟悉JavaScript、不懂ObjC、不了解終端開發的工程師,能通過Rust這種強大的語言開發出邏輯通用的FinClipSDK擴展,最終供小程序開發者使用。
本文的示范代碼在?。
原文:
C語言中,字符串格式化效率對嵌入式項目至關重要,特別是在處理大量日志信息時。 盡管 sprintf 傳統上被用于此,但在性能敏感的場景下,可能需要尋找優化策略。 本文將探討提升數字格式化到字符串效率的方法。 首先,最基礎的格式化方法雖然快捷,但在百萬次以上操作時,效率差距明顯。 例如,將 long 型數字手動格式化為字符串,相比系統自帶的函數,速度大約慢3倍。 盡管測試結果可能因環境而異,但差距是顯著的。 測試2中,混合格式化字符串和數字時,雖然使用自定義函數 Long2String 更節省時間,但它的局限在于只能處理數字。 當需要同時處理數字和字符串時,sprintf 的靈活性使其更高效。 sprintf 的底層機制利用可變參數,通過 va_list、va_start、va_arg 和 va_end 等宏定義實現。 通過理解這個機制,我們可以優化代碼,減少不必要的內存操作,從而提高執行速度。 總的來說,雖然自定義函數在某些特定情況下表現優秀,但對于通用格式化需求,利用 sprintf 或其優化版本能提供更好的性能。 對于C語言開發者來說,理解這些細節并根據項目需求選擇合適的工具是提升效率的關鍵。
內容聲明:
1、本站收錄的內容來源于大數據收集,版權歸原網站所有!
2、本站收錄的內容若侵害到您的利益,請聯系我們進行刪除處理!
3、本站不接受違法信息,如您發現違法內容,請聯系我們進行舉報處理!
4、本文地址:http://m.sycxjdsbhs.com/article/ae82b7e5aa3d5a8a96fb.html,復制請保留版權鏈接!
窗口失蹤之謎您是否遇到過這樣的情況,正在使用計算機時,某個窗口突然消失無蹤,您四處尋找,但它就是找不到了,這種現象稱為窗口失蹤,可能是由多種因素造成的,其中之一就是桌面云,什么是桌面云,桌面云是一種云計算服務,它將虛擬桌面環境,VDI,交付給用戶,也就是說,您的桌面和應用程序不再存儲在本地計算機上,而是存儲在遠程服務器中,用戶可以通過...。
本站公告 2024-09-28 07:55:29
引言在當今信息時代,訪問和管理數據變得至關重要,Web門戶可以提供一個一站式的平臺,用于輕松檢索和操作數據,通過結合ASP,ActiveServerPages,和Access數據庫,我們可以構建功能強大的Web門戶,簡化數據管理并提高效率,ASP的概述ASP是一種服務器端腳本語言,允許開發人員創建動態Web頁面,它可以讓Web頁面與用...。
最新資訊 2024-09-27 18:44:19
引言Java運行時環境,JRE,是Java開發和部署環境的核心組件,它提供了一個可執行Java程序并使其與底層操作系統交互的平臺,本文深入探討JRE的架構、組件和功能,揭示其在Java生態系統中的關鍵作用,JRE的組件JRE由以下主要組件組成,Java虛擬機,JVM,負責執行Java字節碼并管理Java程序的內存和資源,類庫,包含供...。
技術教程 2024-09-27 17:56:40
NumPy是Python中用于科學計算的強大庫,它提供了強大的多維數組對象,可以輕松地存儲和處理大量數據,NumPy數組概述NumPy數組是一個固定長度、同種數據類型的數據集合,它可以用以下方式創建,importnumpyasnp從列表創建數組my,array=np.array,[1,2,3,4,5],從范圍創建數組my,array=...。
本站公告 2024-09-24 21:51:11
如果您正在尋找一種方法來提升您的電影剪輯技能,那么Movieclip正是您所需要的,Movieclip是一款功能強大的電影剪輯軟件,它提供了廣泛的功能,可幫助您創建專業的視頻,如果您是電影剪輯的新手或經驗豐富的專業人士,Movieclip都能提供適合您的東西,Movieclip的主要功能可調節的時間線,可輕松編輯視頻剪輯廣泛的效果和過...。
技術教程 2024-09-24 08:10:50
氣候變化的現實氣候變化已經成為我們時代最嚴峻的挑戰之一,由于人類活動釋放的溫室氣體,地球的大氣層正在變暖,導致極端天氣事件、海平面上升和生物多樣性喪失等一系列毀滅性影響,這些變化對地球上的每一個生態系統都產生了深遠的影響,從北極的冰蓋融化到熱帶雨林的干旱,氣候變化正在對生態系統的結構和功能造成不可逆轉的改變,氣候變化對生態系統的影響以...。
本站公告 2024-09-15 21:23:19
量交付的方式,他們能夠更靈活地響應客戶需求并交付高質量的產品,結論Scrum是一個強大的敏捷框架,它可以通過協作、透明度和適應性幫助團隊有效地開發產品,通過遵循本指南中概述的步驟和最佳實踐,初學者可以有效地從頭開始掌握Scrum,...。
互聯網資訊 2024-09-13 10:43:08
簡介隨著應用程序變得越來越復雜,性能優化變得至關重要,PHP提供了一系列策略和技術,可以幫助您優化應用程序的效率并改善用戶體驗,本文將深入探討PHP中的性能優化,并提供分步指南,幫助您實施這些策略,性能優化策略1.緩存緩存是在內存中存儲數據的過程,以便可以快速檢索,在PHP中,可以通過使用memcached、Redis等緩存系統來實現...。
最新資訊 2024-09-12 22:06:10
引言JavaWeb服務是基于HTTP協議的分布式計算技術,它允許應用程序跨平臺、跨語言和跨網絡進行通信,本文將深入剖析JavaWeb服務技術,涵蓋其構建、部署和最佳實踐,構建Web服務服務端編寫服務接口服務接口定義了Web服務提供的操作,它是一個Java接口,擴展了`javax.jws.WebService`注解,并包含操作方法,``...。
本站公告 2024-09-12 15:42:53
簡介云數據庫備份是確保云數據庫數據安全和可用性的重要方面,傳統的備份方法可能會很復雜、耗時且成本高昂,利用云功能,我們可以簡化和優化云數據庫備份,從而降低成本、提高效率并改善數據保護,本文將重點介紹如何使用云功能將云數據庫備份到本地,從而獲得這些優勢,云功能的好處自動化,云功能使備份過程自動化,從而減少了手動工作并提高了可靠性,按需定...。
最新資訊 2024-09-12 09:30:43
JavaScript是一種功能強大的編程語言,可用于創建動態和交互式的網頁,它提供各種方法來處理日期和時間信息,包括獲取當前月份,使用Date對象獲取當前月份的最常用方法是使用Date對象,constdate=newDate,console.log,date.getMonth,輸出當前月份,0,11,getMonth,...。
互聯網資訊 2024-09-10 09:01:14
編程是一種讓計算機按照指令執行特定任務的過程,它是一種強大的工具,可以用來解決問題、自動化任務、創建應用程序等等,為什么學習編程,學習編程有很多好處,包括,解決問題的能力提高,編程需要分析問題并將其分解成可管理的部分,從而提高你的解決問題能力,自動化任務,編程可以讓你編寫腳本和程序來自動化重復的任務,節省時間和精力,創建應用程序,你可...。
技術教程 2024-09-08 13:02:17