




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、Linux庫詳解1 庫基本概念1.1 庫的分類 有兩種說法,如果熟悉WIN平臺下的DLL,相信不難理解: 庫可以有三種使用的形式:靜態(tài)、共享和動態(tài)。靜態(tài)庫的代碼在編譯時就已連接到開發(fā)人員開發(fā)的應(yīng)用程序中,而共享庫只是在程序開始運(yùn)行時才載入,在編譯時, 只是簡單地指定需要使用的庫函數(shù)。動態(tài)庫則是共享庫的另一種變化形式。動態(tài)庫也是在程序運(yùn)行時載入,但與共享庫不同的是,使用的庫函數(shù)不是在程序運(yùn)行開 始,而是在程序中的語句需要使用該函數(shù)時才載入。動態(tài)庫可以在程序運(yùn)行期間釋放動態(tài)庫所占用的內(nèi)存,騰出空間供其它程序使用。由于共享庫和動態(tài)庫并沒有在程序中包括庫函數(shù)的內(nèi)容,只是包含了對庫函數(shù)的引用,因此代碼的
2、規(guī)模比較小。 Linux下的庫文件分為共享庫和靜態(tài)庫兩大類,它們兩者的差別僅在程序執(zhí)行時所需的代碼是在運(yùn)行時動態(tài)加載的,還是在編譯時靜態(tài)加載的。區(qū)分庫類型最好的方法是看它們的文件后綴,通常共享庫以.so(Shared Object的縮寫)結(jié)尾,靜態(tài)鏈接庫通常以.a結(jié)尾(Archive的縮寫)。在終端缺省情況下,共享庫通常為綠色,而靜態(tài)庫為黑色。 已經(jīng)開發(fā)的大多數(shù)庫都采取共享庫的方式。ELF格式的可執(zhí)行文件使得共享庫能夠比較容易地實(shí)現(xiàn),當(dāng)然使用舊的a.out模式也可以實(shí)現(xiàn)庫的共享。Linux系統(tǒng)中目前可執(zhí)行文件的標(biāo)準(zhǔn)格式為ELF格式。 .a的是為了支持較老的a.out格式的可執(zhí)行文件的 .so的
3、是支持elf格式的可執(zhí)行文件的庫。 .a是靜態(tài)庫文件,可以用ar 命令生成。 .so是動態(tài)庫文件,編譯時加上指定的選項即可生成,具體選項看相應(yīng)的系統(tǒng)文檔了。1.2 庫的命名規(guī)則GNU庫的使用必須遵守Library GNU Public License(LGPL許可協(xié)議)。該協(xié)議與GNU許可協(xié)議略有不同,開發(fā)人員可以免費(fèi)使用GNU庫進(jìn)行軟件開發(fā),但必須保證向用戶提供所用的庫函數(shù)的源代碼。庫的命名和約定:(1)所以的庫都以lib開頭,許多開發(fā)工具都依賴這個約定,特別是GCC,它會在-l選項所指定的文件名前自動地插入lib. (2)文件名以.a(代表存檔,archive)結(jié)尾的庫都是靜態(tài)庫,文件名以
4、.so(代表共享目標(biāo)文件,shared object)結(jié)尾的庫都是共享庫,例如,libdl.a是一個靜態(tài)庫,而libc.so是一個共享庫。采用舊的a.out格式的共享庫的后綴名為.sa。(3) 以_g和_p結(jié)尾的庫,如libform_g.a和libfor_p.a,是基本庫libform的特殊版本。通常以_g結(jié)尾的庫是調(diào)試庫,它們編入了特殊的符號和功能,能夠增加對采用了這個庫的應(yīng)用程序進(jìn)行調(diào)試的能力。類似地,代碼剖析(profiling)庫通常在名字后面附加_p,他們包含地代碼和符號能夠進(jìn)行復(fù)雜地代碼剖析和性能分析。如果你使用了這些庫中的某一個,那么一旦完成調(diào)試或剖析工作,需要使用基本庫重新編譯
5、你的程序。庫名的一般格式為:libname.major_num.minor_num.patch_num, 例如,libgdbm.so.2.0.0, libgdbm.so是庫libname, major_num是2,minor_num和patch_num均為0.系統(tǒng)中可用的庫都存放在/usr/lib和/lib目錄中。這里的name可以是任何字符串,用來唯一標(biāo)識某個庫。該字符串可以是一個單字、幾個字符、甚至一個字母。數(shù)學(xué)共享庫的庫名為libm.so.5,這里的標(biāo)識字符為m,版本號為5。libm.a則是靜態(tài)數(shù)學(xué)庫。X-Windows庫名為libX11.so.6,這里使用X11作為庫的標(biāo)識,版本號為6
6、。每個共享函數(shù)庫都有個特殊的名字,稱作“soname”。Soname名字命名必須以“l(fā)ib”作為前綴,然后是函數(shù)庫的名字,然后是“.so”,最后是版本號信息。不過有個特例,就是非常底層的C庫函數(shù)都不是以lib開頭這樣命名的。每個共享函數(shù)庫都有一個真正的名字(“real name”),它是包含真正庫函數(shù)代碼的文件。真名有一個主版本號,和一個發(fā)行版本號。最后一個發(fā)行版本號是可選的,可以沒有。主版本號和發(fā)行版本號使你可以知道你到底是安裝了什么版本的庫函數(shù)。另外,還有一個名字是編譯器編譯的時候需要的函數(shù)庫的名字,這個名字就是簡單的soname名字,而不包含任何版本號信息。管理共享函數(shù)庫的關(guān)鍵是區(qū)分好這
7、些名字。當(dāng)可執(zhí)行程序需要在自己的程序中列出這些他們需要的共享庫函數(shù)的時候,它只要用soname就可以了;反過來,當(dāng)你要創(chuàng)建一個新的共享函數(shù)庫的時候,你要指定一個特定的文件名,其中包含很細(xì)節(jié)的版本信息。當(dāng)你安裝一個新版本的函數(shù)庫的時候,你只要先將這些函數(shù)庫文件拷貝到一些特定的目錄中,運(yùn)行l(wèi)dconfig這個實(shí)用就可以。Ldconfig檢查已經(jīng)存在的庫文件,然后創(chuàng)建soname的符號鏈接到真正的函數(shù)庫,同時設(shè)置/etc/ld.so.cache這個緩沖文件。這個我們稍后再討論。Ldconfig并不設(shè)置鏈接的名字,通常的做法是在安裝過程中完成這個鏈接名字的建立,一般來說這個符號鏈接就簡單的指向最新的s
8、oname或者最新版本的函數(shù)庫文件。最好把這個符號鏈接指向soname,因為通常當(dāng)你升級你的庫函數(shù)后,你就可以自動使用新版本的函數(shù)庫。我們來舉例看看:/usr/lib/libreadline.so.3 是一個完全的完整的soname,ldconfig可以設(shè)置一個符號鏈接到其他某個真正的函數(shù)庫文件,例如是 /usr/lib/libreadline.so.3.0。同時還必須有一個鏈接名字,例如/usr/lib/libreadline.so 就是一個符號鏈接指向/usr/lib/libreadline.so.3。2 庫操作命令 Linux庫操作可以使用命令完成,目前常用的命令是ldd和ldconfi
9、g。2.1 ldd ldd是Library Dependency Display縮寫,它的作用是顯示一個可執(zhí)行程序必須使用的共享庫。 $ ldd /usr/bin/mesg libc.so.6 = /lib/tls/i686/cmov/libc.so.6 (0xb7eaf000) /lib/ld-linux.so.2 = /lib/ld-linux.so.2 (0xb7feb000)2.2 ldconfig 庫安裝到系統(tǒng)以后,為了讓動態(tài)鏈接庫為系統(tǒng)所認(rèn)識及共享,就需要運(yùn)行l(wèi)dconfig。ldconfig命令的用途,主要是在默認(rèn)搜尋目錄(/lib和 /usr/lib)以及動態(tài)庫配置文件/etc
10、/ld.so.conf內(nèi)所列的目錄下,搜索出可共享的動態(tài)鏈接庫(格式如lib*.so*),進(jìn)而創(chuàng)建出動態(tài)裝入程序(ld.so)所需的連接和緩存文件。緩存文件默認(rèn)為/etc/ld.so.cache,此文件保存已排好序的動態(tài)鏈接庫名字列表, ldconfig通常在系統(tǒng)啟動時運(yùn)行,而當(dāng)用戶安裝了一個新的動態(tài)鏈接庫時,就需要手工運(yùn)行這個命令。(1)命令格式 ldconfig 選項 libs(2)主要選項 -v或-verbose ldconfig將顯示正在掃描的目錄、搜索到的動態(tài)鏈接庫,以及它所創(chuàng)建的連接的名字。 -f CONF 指定動態(tài)鏈接庫的配置文件為CONF,系統(tǒng)默認(rèn)為/etc/ld.so.con
11、f。 -C CACHE 指定生成的緩存文件為CACHE,系統(tǒng)默認(rèn)的是/etc/ld.so.cache,文件存放已排好序的可共享的動態(tài)鏈接庫的列表。 -p或-print-cache 讓ldconfig打印出當(dāng)前緩存文件所保存的所有共享庫的名字。 -r ROOT 改變應(yīng)用程序的根目錄為ROOT。 n ldconfig僅掃描命令行指定的目錄,不掃描默認(rèn)目錄(/lib、/usr/lib),也不掃描配置文件/etc/ld.so.conf所列的目錄。 運(yùn)行沒有選項的ldconfig命令時,用于更新高速緩沖文件。這個命令主要用于高速緩沖DNS服務(wù)器(Caching DNS Server)。高速緩沖DNS服務(wù)
12、器的原理是提供查詢的歷史記錄,并且利用這些記錄來提高查詢的效率。當(dāng)某個查詢是第一次被發(fā)送到高速緩沖DNS服務(wù)器時,高速緩沖DNS服務(wù)器就將此查詢的整個過程記錄下來,在一定的時期內(nèi)用它來回答所有相同的查詢,從而減少整個DNS系統(tǒng)的負(fù)擔(dān)并且提高查詢速度。3 庫的路徑問題為了讓執(zhí)行程序順利找到動態(tài)庫,有三種方法:(1)把庫拷貝到/usr/lib和/lib目錄下。(2)在LD_LIBRARY_PATH環(huán)境變量中加上庫所在路徑。例如動態(tài)庫libhello.so在/home/ting/lib目錄下,以bash為例,使用命令:$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:
13、/home/ting/lib(3) 修改/etc/ld.so.conf文件,把庫所在的路徑加到文件末尾,并執(zhí)行l(wèi)dconfig刷新。這樣,加入的目錄下的所有庫文件都可見4 查看庫中的符號有時候可能需要查看一個庫中到底有哪些函數(shù),nm命令可以打印出庫中的涉及到的所有符號。庫既可以是靜態(tài)的也可以是動態(tài)的。nm列出的符號有很多,常見的有三種,一種是在庫中被調(diào)用,但并沒有在庫中定義(表明需要其他庫支持),用U表示;一種是庫中定義的函數(shù),用T表示,這是最常見的;另外一種是所謂的 “弱態(tài)”符號,它們雖然在庫中被定義,但是可能被其他庫中的同名符號覆蓋,用W表示。例如,假設(shè)開發(fā)者希望知道上文提到的hello庫
14、中是否定義了 printf():$nm libhello.so |grep printfU printfU表示符號printf被引用,但是并沒有在函數(shù)內(nèi)定義,由此可以推斷,要正常使用hello庫,必須有其它庫支持,再使用ldd命令查看hello依賴于哪些庫:$ldd hellolibc.so.6=/lib/libc.so.6(0x400la000)/lib/ld-linux.so.2=/lib/ld-linux.so.2 (0x40000000)從上面的結(jié)果可以繼續(xù)查看printf最終在哪里被定義,有興趣可以go on5 庫升級Linux系統(tǒng)軟件更新很快,新的核心幾乎每幾個星期就公布一次,其它
15、軟件的更新也是非常頻繁。多數(shù)情況下,盲目跟隨潮流的升級并不必要,如果確實(shí)需要新版本的特性時再升級。換句話說,不要為了升級而升級。Linux系統(tǒng)中多數(shù)軟件都是用共享庫來編譯的,其中包含了在不同程序之間共享的公用子例程。在運(yùn)行某個程序時,如果看到如下信息:“Incompatible library version”則表明需要將該庫升級到程序所需要的版本。庫是向下兼容的,也就是說,用老版本庫編譯的程序可以在新安裝的版本庫上運(yùn)行,反之則不行。Linux庫函數(shù)的升級是一項重要的工作,往往與其它軟件包的升級有一定關(guān)聯(lián)作用,所以操作前一定要備份文件。下面看一下如何把Glibc 2.2.4.13升級至2.3.
16、2版本,其過程如下: 1.下載.gz壓縮文件并解壓在GUN C網(wǎng)站下載的四個.gz壓縮文件,解壓至一臨時目錄中:cd /usr/caolinuxtar xzvf glibc-2.3.2.tar.gzcd glibc-2.3.2tar xzvf ./glibc-linuxthreads-2.3.2.tar.gztar xzvf ./glibc-crypt-2.3.2.tar.gztar xzvf ./glibc-localedata-2.3.2.tar.gz 2.建立庫函數(shù)的安裝目錄mkdir /usr/higlibccd /usr/higlibc 3.建立編譯目錄mkdir caocd cao
17、./configure -enable-add-ons=linuxthreads,crypt,localedata -prefix=/usr/higlibc 4.編譯與安裝makemake checkmake install 5.改變數(shù)據(jù)庫的鏈接ln -s /usr/higlibc/lib/ld-linux.so.2 /lib/ld-linux.so.2然后,修改/etc/ld.so.conf,加入一行/usr/higlibc/lib,執(zhí)行下面代碼:ldconfig -v更新/etc/ld.so.cache的內(nèi)容,列出每個庫的版本號,掃描目錄和所要創(chuàng)建及更新的鏈接。 6.更改GCC設(shè)置cd /
18、usr/lib/gcc-libcp -r i386-redhat-linux higlibc 7.更新符號鏈接cd /usr/higlibc/includeln -s /usr/src/linux/include/linuxln -s /usr/src/linux/include/asmln -s /usr/X11R6/include/X118.測試并完成6 高級共享庫特性6.1 soname為了在同一系統(tǒng)中使用不同版本的庫,可以在庫文件名后加上版本號為后綴,例如: libhello.so.1.0,由于程序連接默認(rèn)以.so為文件后綴名。所以為了使用這些庫,通常使用建立符號連接的方式。ln -s
19、 libhello.so.1.0 libhello.so.1ln -s libhello.so.1 libhello.so共享庫的一個非常重要的,也是非常難的概念是 soname簡寫共享目標(biāo)名(short for shared object name)。這是一個為共享庫(.so)文件而內(nèi)嵌在控制數(shù)據(jù)中的名字。如前面提到的,每一個程序都有一個需要使用的庫的清單。這個清單的內(nèi)容是一系列庫的 soname,如同 ldd 顯示的那樣,共享庫裝載器必須找到這個清單。soname 的關(guān)鍵功能是它提供了兼容性的標(biāo)準(zhǔn)。當(dāng)要升級系統(tǒng)中的一個庫時,并且新庫的 soname 和老的庫的 soname 一樣,用舊庫連
20、接生成的程序,使用新的庫依然能正常運(yùn)行。這個特性使得在 Linux 下,升級使用共享庫的程序和定位錯誤變得十分容易。在 Linux 中,應(yīng)用程序通過使用 soname,來指定所希望庫的版本。庫作者也可以通過保留或者改變 soname 來聲明,哪些版本是相互兼容的,這使得程序員擺脫了共享庫版本沖突問題的困擾。查看/usr/local/lib 目錄,分析 MiniGUI 的共享庫文件之間的關(guān)系6.2 共享庫裝載器當(dāng)程序被調(diào)用的時候,Linux 共享庫裝載器(也被稱為動態(tài)連接器)也自動被調(diào)用。它的作用是保證程序所需要的所有適當(dāng)版本的庫都被調(diào)入內(nèi)存。共享庫裝載器名字是 ld.so 或者是 ld-lin
21、ux.so,這取決于 Linux libc 的版本,它必須使用一點(diǎn)外部交互,才能完成自己的工作。然而它接受在環(huán)境變量和配置文件中的配置信息。文件 /etc/ld.so.conf 定義了標(biāo)準(zhǔn)系統(tǒng)庫的路徑。共享庫裝載器把它作為搜索路徑。為了改變這個設(shè)置,必須以 root 身份運(yùn)行 ldconfig 工具。這將更新 /etc/ls.so.cache 文件,這個文件其實(shí)是裝載器內(nèi)部使用的文件之一。6.3 使用 dlopen另外一個強(qiáng)大的庫函數(shù)是 dlopen()。該函數(shù)將打開一個新庫,并把它裝入內(nèi)存。該函數(shù)主要用來加載庫中的符號,這些符號在編譯的時候是不知道的。比如 Apache Web 服務(wù)器利用這
22、個函數(shù)在運(yùn)行過程中加載模塊,這為它提供了額外的能力。一個配置文件控制了加載模塊的過程。這種機(jī)制使得在系統(tǒng)中添加或者刪除一個模塊時,都不需要重新編譯了??梢栽谧约旱某绦蛑惺褂?dlopen()。dlopen() 在 dlfcn.h 中定義,并在 dl 庫中實(shí)現(xiàn)。它需要兩個參數(shù):一個文件名和一個標(biāo)志。文件名可以是我們學(xué)習(xí)過的庫中的 soname。標(biāo)志指明是否立刻計算庫的依賴性。如果設(shè)置為 RTLD_NOW 的話,則立刻計算;如果設(shè)置的是 RTLD_LAZY,則在需要的時候才計算。另外,可以指定 RTLD_GLOBAL,它使得那些在以后才加載的庫可以獲得其中的符號。當(dāng)庫被裝入后,可以把 dlopen
23、() 返回的句柄作為給 dlsym() 的第一個參數(shù),以獲得符號在庫中的地址。使用這個地址,就可以獲得庫中特定函數(shù)的指針,并且調(diào)用裝載庫中的相應(yīng)函數(shù)。7 動態(tài)庫的編寫和使用現(xiàn)在假設(shè)有一個叫hello的程序開發(fā)包,它提供一個靜態(tài)庫libhello.a 一個動態(tài)庫libhello.so,一個頭文件hello.h,頭文件中提供sayhello()這個函數(shù)/* hello.h */void sayhello();另外還有一些說明文檔。這是一個典型的程序開發(fā)包結(jié)構(gòu)。7.1 生成庫第一步要把源代碼編繹成目標(biāo)代碼。以下面的代碼為例,生成上面用到的hello庫:/* hello.c */#include vo
24、id sayhello()printf(hello,worldn);用gcc編繹該文件,在編繹時可以使用任何合法的編繹參數(shù),例如-g加入調(diào)試代碼等:gcc -c hello.c -o hello.o1.連接成靜態(tài)庫連接成靜態(tài)庫使用ar命令,其實(shí)ar是archive的意思$ar cqs libhello.a hello.o2.連接成動態(tài)庫生成動態(tài)庫用gcc來完成,由于可能存在多個版本,因此通常指定版本號:$gcc -shared -Wl, -soname, libhello.so.1 -o libhello.so.1.0 hello.o另外再建立兩個符號連接:$ln -s libhello.so
25、.1.0 libhello.so.1$ln -s libhello.so.1 libhello.so這樣一個libhello的動態(tài)連接庫就生成了。最重要的是傳gcc -shared 參數(shù)使其生成是動態(tài)庫而不是普通執(zhí)行程序。-Wl 表示后面的參數(shù)也就是-soname,libhello.so.1直接傳給連接器ld進(jìn)行處理。實(shí)際上,每一個庫都有一個soname,當(dāng)連接器發(fā)現(xiàn)它正在查找的程序庫中有這樣一個名稱,連接器便會將soname嵌入連結(jié)中的二進(jìn)制文件內(nèi),而不是它正在運(yùn)行的實(shí)際文件名,在程序執(zhí)行期間,程序會查找擁有 soname名字的文件,而不是庫的文件名,換句話說,soname是庫的區(qū)分標(biāo)志。這
26、樣做的目的主要是允許系統(tǒng)中多個版本的庫文件共存,習(xí)慣上在命名庫文件的時候通常與soname相同:libxxxx.so.major.minor 其中,xxxx是庫的名字,major是主版本號,minor 是次版本號。7.2 使用庫當(dāng)要使用靜態(tài)的程序庫時,連接器會找出程序所需的函數(shù),然后將它們拷貝到執(zhí)行文件,由于這種拷貝是完整的,所以一旦連接成功,靜態(tài)程序庫也就不再需要了。 然而,對動態(tài)庫而言,就不是這樣。動態(tài)庫會在執(zhí)行程序內(nèi)留下一個標(biāo)記指明當(dāng)程序執(zhí)行時,首先必須載入這個庫。由于動態(tài)庫節(jié)省空間,linux下進(jìn)行連接 的缺省操作是首先連接動態(tài)庫,也就是說,如果同時存在靜態(tài)和動態(tài)庫,不特別指定的話,將
27、與動態(tài)庫相連接。1.與動態(tài)庫連接linux默認(rèn)的就是與動態(tài)庫連接,下面這段程序testlib.c使用hello庫中的sayhello()函數(shù)/*testlib.c*/#include #include int main()sayhello();return 0;使用如下命令進(jìn)行編譯$gcc -c testlib.c -o testlib.o用如下命令連接:$gcc testlib.o -lhello -o testlib在連接時要注意,假設(shè)libhello.o 和libhello.a都在缺省的庫搜索路徑下/usr/lib,如果在其它位置要加上-L參數(shù)2. 與靜態(tài)庫連接與靜態(tài)庫連接麻煩一些,主要是參數(shù)問題。還是上面的例子:$gc
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 醫(yī)療器械認(rèn)證的現(xiàn)場審查與審核流程考核試卷
- 隧道支護(hù)設(shè)計考核試卷
- 企業(yè)環(huán)境績效與社會責(zé)任報告編制規(guī)范考核試卷
- 兔舍建設(shè)成本控制與養(yǎng)殖行業(yè)標(biāo)準(zhǔn)化推進(jìn)研究考核試卷
- 廢氣處理技術(shù)綠色化學(xué)與清潔生產(chǎn)理念融合研究考核試卷
- 交通基礎(chǔ)設(shè)施布局與城市居民出行公平性研究考核試卷
- 計劃生育練習(xí)試卷1(共388題)
- 做最好的員工演講稿
- 保安公司工作總結(jié)
- 畢業(yè)生創(chuàng)意線上活動方案
- 動物園野生動物馴養(yǎng)繁殖或馴養(yǎng)觀賞可行性研究報告
- 江蘇2024年江蘇省美術(shù)館招聘筆試歷年典型考題及考點(diǎn)附答案解析
- 2023-2024學(xué)年浙江省杭州市小升初考試數(shù)學(xué)試卷含解析
- DZ∕T 0215-2020 礦產(chǎn)地質(zhì)勘查規(guī)范 煤(正式版)
- GB/T 3428-2024架空導(dǎo)線用鍍鋅鋼線
- 中國特色社會主義民族發(fā)展理論研究
- 《責(zé)任勝于能力》課件
- GB/T 5465.2-2023電氣設(shè)備用圖形符號第2部分:圖形符號
- 廢氣治理設(shè)施運(yùn)行管理規(guī)程制度
- 市政工程質(zhì)量通病防治措施
- 漢字的發(fā)展(英文版介紹)Chinese-character
評論
0/150
提交評論