版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、Lib庫使用學(xué)習筆記一、 Chapter 1.為什么使用庫文件我們在實際編程工作中肯定會遇到這種情況:有幾個項目里有一些函數(shù)模塊的功能相同,實現(xiàn)代碼也相同,也是我們所說的重復(fù)代碼。比如,很多項目里都有一個用戶驗證的功能。代碼段如下:/UserLogin.h文件,提供函數(shù)聲明int lsValidUser(char* user name, int n amele n);/UserLogin.c文件,實現(xiàn)對用戶信息的驗證int IsValidUser(char* user name, int n amele n)int IsValid = 0;/*下面是具體的處理代碼,略去 */return Is
2、Valid;如果每個項目都保存著這兩個UserLogin.h和UserLogin.c文件,會有以下幾個弊端:1. 每個項目里都有重復(fù)的模塊,造成代碼重復(fù)。2. 代碼的重用性不好,一旦IsValidUser的代碼發(fā)生了變化,為了保持設(shè)計的一致性,我們還要手工修改其他項目里的UserLogin.c文件,既費時又費力,還容易出錯。庫文件就是對公共代碼的一種組織形式。為了解決上面兩個弊端,就提出了用庫文件存放公共代碼的解決方案,其要點就是把公共的(也就是可以被多次復(fù)用的) 目標代碼從項目中分離出來, 統(tǒng)一存放到庫文件中, 項目要用 到這些代碼的時候,在編譯或者運行的時候從庫文件中取得目標代碼即可。庫文
3、件又分兩種:靜態(tài)庫和動態(tài)庫。Chapter 2.靜態(tài)庫和動態(tài)庫簡單的說,如果程序是在編譯時加載庫文件的,就是使用了靜態(tài)庫,靜態(tài)庫的文件名格式是lib*.a。如果是在運行時加載目標代碼,就成為動態(tài)庫,動態(tài)庫的文件名格式是lib*.so.*。 換句話說,如果是使用靜態(tài)庫,則靜態(tài)庫代碼在編譯時就拷貝到了程序的代碼段,程序的體積會膨脹。如果使用動態(tài)庫,則程序中只保留庫文件的名字和函數(shù)名,在運行時去查找?guī)煳募秃瘮?shù)體,程序的體積基本變化不大。靜態(tài)庫的原則是 以空間換時間”,增加程序體積,減少運行時間;動態(tài)庫則是以時間換空間”,增加了運行時間,但減少了程序本身的體積。在附錄的PIC部分,也會做一些說明。從
4、文件的格式角度講,靜態(tài)庫的本質(zhì)是一種檔案文件(.0文件的集合),其中包含了一個內(nèi)容索引 (也可以不包含,但沒有索引的靜態(tài)庫不能用來鏈接,在附錄的ar和各個模塊既.0文件;而動態(tài)庫是 ELF格式的文件,可以被用來加載和執(zhí)行,而靜態(tài)庫不可以。還有一種庫文件,共享庫??吹骄W(wǎng)上有些資料說,動態(tài)庫就是共享庫的一種變種,由于沒有使用到,沒有詳細研究。有時候,會在目錄中看到以 .la或.lo結(jié)尾的文件,這些是 GNU的工具libtool生成和使用 的文件, 用來說明實際庫文件的使用信息和以來關(guān)系,詳細的內(nèi)容會在以后automakeautoconf and libtool 的文檔中介紹。三、Chapter 3
5、.靜態(tài)庫的生成和使用3.1. 制作最簡單的靜態(tài)庫文件編寫如下兩個文件,放在同一目錄中:mylib.h II靜態(tài)庫頭文件void test();mylib.c II靜態(tài)庫實現(xiàn)文件#in elude void test()prin tf(hello world./n ”);使用下邊的命令生成靜態(tài)庫:gee -c mylib.car rc libmy.a mylib.o這樣就生成了靜態(tài)庫libmy.a,注意一定要以lib*.a這樣的格式命名,否則鏈接器 ld不能識 別。使用命令file libmy.a看看它的格式,是一個檔案文件。我們可以使用nm查看它的內(nèi)部構(gòu)成:root Be nson libte
6、st# nm libmy.alibmy.o:U printf00000000 T test這表示靜態(tài)庫有模塊libmy.o,在使用的時候,gcc會根據(jù)需要將函數(shù)名得到模塊,然后從靜態(tài)庫中提取出對應(yīng)的.0文件的內(nèi)容,然后用來鏈接,就是使用單獨的.0文件一樣。32使用庫文件編寫一個測試程序 mai n.c,內(nèi)容為:#i nclude mylib.hint mai n(void)test();return 0;由于需要調(diào)用libmy.a中的test函數(shù),所以在編譯時,需通過-L -l參數(shù)指定鏈接這個庫:gcc -I./ -o main main.c -L./ -lmy通過-I和-L參數(shù)制定了 gcc
7、的頭文件和庫文件搜索路徑為當前目錄,也可以根據(jù)需要指定為 其他目錄。生成執(zhí)行文件 main后,執(zhí)行命令file ma in ”,可以看到:root Be nson libtest# file mainmain: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, staticlly linked (uses shared libs), not stripped運行,看到結(jié)果,成功。四、Chapter 4.動態(tài)庫的生成和使用4.1. 制作最簡單的動態(tài)庫文件我們同樣使用上邊的mylib.h和m
8、ylib.c文件,但使用不同的命令生成庫文件:gcc -fpic -shared libmy.so libmy.c這樣就生成了動態(tài)庫文件libmy.so,-fpic這個選項指定是否使用PIC這個選項的使用需要系統(tǒng)平臺的支持,一般建議添加,如果不支持,gcc會報錯。生成libmy.so后,使用file libmy.so命令,可以看到是一個ELF格式的文件,這說明共享庫的 使用需要通過符號解析和重定位加載入內(nèi)存才能使用。4.2. 動態(tài)庫的隱式調(diào)用動態(tài)庫有兩種使用方法,隱式調(diào)用和顯示調(diào)用。隱式調(diào)用的方法跟靜態(tài)庫的使用方法一樣, 都是通過gcc的-I -L 參數(shù)指定庫文件的路徑,如果同一個庫文件,在系
9、統(tǒng)中同時存在靜態(tài)庫和動態(tài)庫,默認情況下gcc主動鏈接動態(tài)庫。但也可以通過 gcc的-static選項,強制指定使用靜態(tài)庫。gcc -I./ -o mai n mai n.c -L./ -Imy # 使用動態(tài)庫生成 ma ingcc ma in .c ./libmy.so -o ma in # 使用動態(tài)庫生成 ma in,不同的地方在于指定了libmy.so的加載路徑,這種用法很少用。詳細的內(nèi)容附錄Id.sogcc -static -I./ -o ma in mai n.c -L./ -Imy # 使用靜態(tài)庫生成 ma in輸入file main命令,可以看到:root Be nson libt
10、est# file mainmain: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5,dyn amically lin ked (uses shared libs), not stripped運行程序,報錯:root Be nson libtest# ./main./main: error while loading shared libraries: libmy.so: cannot open shared object file:No such file or directory沒
11、有找到libmy.so這個動態(tài)庫,我這個庫文件就在當前目錄下?4.3. 使動態(tài)庫被系統(tǒng)共享的方法前邊已經(jīng)說過動態(tài)庫需要加載到內(nèi)存中,才能使用。注意,鏈接和加載是兩碼事,鏈接發(fā)生在生成可執(zhí)行程序的階段,加載發(fā)生在運行階段。gcc的-I -L參數(shù)只是保證在鏈接階段指定文件路徑,和加載無關(guān),當然也有辦法可以使鏈接階段的路徑信息在加載階段起作用,這些涉及到gcc的詳細用法,和可執(zhí)行文件的格式,附錄中會簡單介紹一些。運行時的加載的 工作 不是由main完成的,而是由/lib/ld.so (不同平臺會有些出入)完成。他有自己的查找 動態(tài)連接庫的規(guī)則,所以在不更新ld.so的查找路徑的情況下,會出現(xiàn)上邊的錯
12、誤。根據(jù)ld.so的man手冊,ld.so共有六種方式查找需要的動態(tài)庫,這里只介紹常用的三種方式,詳細的內(nèi)容見附錄ld.so1. 按照環(huán)境變量LD_LIBRARY_PAT的內(nèi)容查找(setuid類的程序排除)2. 在庫高速緩存文件ld.so.conf中給出的路徑查找3. 在/lib,/usr/lib目錄下查找相對應(yīng)的,可以分別通過設(shè)置環(huán)境變量LD_LIBRARY_PATH通過在ld.so.conf文件中添加路徑和將 動態(tài)庫文件復(fù)制到/lib、/usr/lib目錄下,使動態(tài)庫可以在加載時被找到。root Be nson libtest# export LD_LIBRARY_PATH=$LD_LI
13、BRARY_PATH:/pwdroot Be nson libtest# cat pwd /etc/ld.so.c onf ; Ide onfigroot Be nson libtest# cp libmy.so /lib -f以上三種方式都可以工作。關(guān)于ldconfig的使用詳解,見 附錄ldconfig此時再執(zhí)行main,可以正常運行了。通過Idd命令,可以看到 main程序依賴于libmy.so。root Benson libtest# Idd mainlibtest.so = not foundlibc.so.6 = /lib/tls/libc.so.6 (0x42000000)/li
14、b/ld -linux.so.2 = /lib/ld -linux.so.2 (0x40000000)4.4. 動態(tài)庫的顯式調(diào)用動態(tài)庫的顯示調(diào)用,也需要庫文件被加載到內(nèi)存中。但是使用方法和靜態(tài)庫完全不同。需要系統(tǒng) 調(diào)用dlopen dlsym dlclose dlerror的支持??梢允褂猛粋€libmy.so文件,但是需要新的測試文件:/* main.c測試動態(tài)庫顯式調(diào)用的程序*/#include /用于動態(tài)庫管理的系統(tǒng)頭文件#i nclude libmy.h /要把函數(shù)的頭文件包含進來,否則編譯時會報錯int mai n(void)/*聲明對應(yīng)的函數(shù)的函數(shù)指針*/void (*pTest)
15、();/*加載動態(tài)庫 */void *pdlHandle = dlopen(libtest.so, RTLD_LAZY);/*錯誤處理*/if(pdlHa ndle = NULL )prin tf(Failed load library/n ”); return -1;char* pszErr = dlerror();if(pszErr != NULL)prin tf(%s/n, pszErr);return -1;/*獲取函數(shù)的地址*/pTest = dlsym(pdlHandle, test); pszErr = dlerror();if(pszErr != NULL)printf(%s/
16、n, pszErr);dlclose(pdlHa ndle);return -1;/*實現(xiàn)函數(shù)調(diào)用*/pTest ();/*程序結(jié)束時關(guān)閉動態(tài)庫*/dlclose(pdlHa ndle);return 0;編譯時需要加入-Idl選項:root Benson libtest# gcc -ldl -o main main.c運行程序,成功。這種方式,不需要在鏈接階段指定動態(tài)庫的位置。在運行階段,調(diào)用要使用的函數(shù)通過ldd命令,可以看到 main程序不再依賴于libmy.so,轉(zhuǎn)為 依賴libdl.solibdl.so.2 = /lib/libdl.so.2 (0x40034000)libc.so.
17、6 = /lib/tls/libc.so.6 (0x42000000)/lib/ld -linux.so.2 = /lib/ld -linux.so.2 (0x40000000)Chapter 5.鏈接時同時使用動態(tài)庫和靜態(tài)庫當一個執(zhí)行程序鏈接時需要多個庫文件時,通常情況下,我們要么統(tǒng)一采用靜態(tài)鏈接,要么統(tǒng)一采用動態(tài)鏈接。實際上,我們可以通過 gcc的選項分別指定每種庫的鏈接方式:-WI-Bstatic ; -Wl -Bdynamic。gcc -o main main.c -Wl -Bstatic -lc -Wl -Bdy namic -test上邊這個例子中制定了靜態(tài)鏈接libc和動態(tài)連接l
18、ibtest。而實際上gcc選項-Wl表示將后邊的參數(shù)傳給鏈接器,-Bstatic和-Bdynamic是ld的選項。Appendix A.附錄A.1. ldconfigIdconfig用來維護ld.so加載的動態(tài)庫的路徑信息和依賴信息,路徑信息存放在/etc/ld.so.conf中,/etc/ld.so.cache中存放了 /lib /usr/lib 和/etc/ld.conf包含的路徑內(nèi)的所有庫信息??梢酝ㄟ^ldd命令查看動態(tài)庫的依賴信息。ldconfig有兩種常用的使用方法:1. 將需要查找的目錄加入/etc/ld.so.conf,然后運行l(wèi)dconfig更新,更新結(jié)果永久有效2. ldc
19、onfig +路徑,這種方式能直接更新指定的目錄,但是結(jié)果在下次執(zhí)行l(wèi)dconfig時,將會失效。Idconfig的選項比較有用的是-v和-n,其他的可參考 man手冊:? -v 或 -verbose 詳細的顯示掃描的目錄及搜索到的動態(tài)連接庫, 還有它所創(chuàng)建的 鏈 接的名字? -n使掃描時,不掃描默認目錄/lib、/usr/lib和/etc/ld.so.conf包含的路徑A.2. lddldd 命令很簡單,用來顯示文件所依賴的動態(tài)庫文件,同樣 -v 選項顯示詳細信息。A.3. arar 命令用來創(chuàng)建歸檔文件,修改歸檔文件,和提取歸檔文件中的模塊。這里歸檔文件就是靜態(tài)庫, 模塊就是里邊的各個 .
20、o 文件。在靜態(tài)庫中每個 .o 文件的內(nèi)容,權(quán)限,時間戳, 文件所有者,文件所屬組 都將被保留,并且可在提取時回復(fù)。 ar 通過在靜態(tài)庫中創(chuàng)建模塊 列表來維護內(nèi)容結(jié)構(gòu)。可以通過 nm -s 命令查看這個列表內(nèi)容。 ar 命令的選項很多,可通 過查看 man 手冊獲取全部內(nèi)容,這里我舉幾個例子來說明 它的主要功能:1. 創(chuàng)建靜態(tài)庫文件:2. ar -rc libtest.a libmy.o libtest.o選項分為r和c。-r表示將后邊的.o模塊加入庫文件中;-c表示當庫文件不存在時創(chuàng) 建。 同樣,向存在的庫文件添加新的模塊時,只需要 -r 選項即可。3. 查看靜態(tài)庫中的模塊:4. root
21、Bensonlibtest# ar -t libtest.a5. libmy.o6. libtest.o7. 刪除靜態(tài)庫中的模塊:8. ar -d libtest.alibmy.o此時在查看庫的模塊, libmy.o 就不存在了。9. 提取靜態(tài)庫中的模塊:10. root Benson libtest# ls11. libtest.a12. root Benson libtest# ar -x libtest.a libmy.o ; ls13. libtest.a libmy.o從 libtest.a 中提取出了 libmy.o 文件A.4. nmnm 命令用來查看目標文件中的符號信息, nm
22、 命令對每個符號顯示如下內(nèi)容:? 每個符號的值。? 當指定-S選項時,顯示函數(shù)符號對應(yīng)的函數(shù)體的大小。? 每個符號的類型,如, U 表示該符號沒有在庫中定義; T 表示該符號在庫中定義。 還有其他的內(nèi)容涉及 到目標文件的格式,這里就不詳細介紹。? 每個符號的名字。man 手冊。nm的選項中,-s選項用來顯示靜態(tài)庫文件的列表信息。其他選項可查看A.5. ranlib為靜態(tài)庫生成索引信息,并將索引信息保存在靜態(tài)庫文件中,它是ar -s命令的變形。帶有索引的 靜態(tài)庫能夠加快連接速度,并允許庫中的函數(shù)相互調(diào)用,而不需要考慮函數(shù)位置的 先后。A.6. PICPIC(Position Independen
23、t Code) ,位置無關(guān)編碼。是一種庫文件的編碼組織方式,其特點是方便系統(tǒng)裝載。是否支持這種格式的動態(tài)庫,與硬件系統(tǒng)平臺有關(guān)。簡單的說,這種格式的庫文件包含兩個符號GOT(_GLOBAL_OFFSET_TABLE_)PLT (ProcedureLinkage Table)。調(diào)用函數(shù)實際調(diào)用的是PLT里的地址,訪問全局變量通過 GOT里邊的地址 這些地址在未運行時不確定, 在加載運行后, 才被解析出來, 所以可以加載到進程地址空間的 任何地方。摘自網(wǎng)絡(luò)的一篇文章,含有更多信息:PIC code radically differs from conventional code in the wa
24、y it calls functions and operates on data variables.It will access these functions and data through an indirection table, the Global Offset Table (GOT), by software convention accessible using the reserved name _GLOBAL_OFFSET_TABLE_. The exact mechanism used for this is hardware architecture depende
25、nt, but usually a special machine register is reserved for setting up the location of the GOT when entering a function.The rationale behind this indirect addressing is to generate code that can be independently accessed of the actual load address.In a true PIC library without relocations in the text
26、 segment, only the symbols exported in the Global Offset Table need updating at run -time depending on the current load address of the various shared libraries in the address space of the running process.Likewise, procedure calls to globally defined functions are redirected through the Procedure Lin
27、kage Table (PLT) residing in the data segment of the core image. Again, this is done to avoid run-time modifications to the text segment.The linker-editor allocates the Global Offset Table and Procedure Linkage Table when combining PIC object files into an image suitable for mapping into the process
28、 address space. It also collects all symbols that may be needed by the run-time link-editor and stores these along with the images text and data bits. Another reserved symbol, _DYNAMIC is used to indicate the presence of the run-time linker structures. Whenever _DYNAMIC is relocated to 0, there is n
29、o need to invoke the run -time link- editor. If this symbol is non -zero, it points at a data structure from which the location of the necessary relocation - and symbol information can be derived. This is most notably used by the start-up module, crt0, crt1S and more recently Scrt1. The _DYNAMIC str
30、ucture is conventionally located at the start of the data segment of the image to which it pertains.On most architectures, when you compile source code to object code, you need to specify whether the object code should be position independent or not. There are occasional architectures which dont mak
31、e the distinction, usually because all object code is position independent by virtue of the Application Binary Interface (ABI), or less often because the load address of the object is fixed at compile time, which implies that shared libraries are not supported by such a platform). If an object is co
32、mpiled as position independent code (PIC), then the operating system can load the object at any address in preparation for execution. This involves a time overhead, in replacing direct address references with relative addresses at compile time, and a space overhead, in maintaining information to hel
33、p the runtime loader fill in the unresolved addresses at runtime. Consequently, PIC objects are usually slightly larger and slower at runtime than the equivalent non -PIC object. The advantage of sharing library code on disk and in memory outweigh these problems as soon as the PIC object code in sha
34、red libraries is reused.PIC compilation is exactly what is required for objects which will become part of a shared library. Consequently, libtool builds PIC objects for use in shared libraries and non -PIC objects for use in static libraries. Whenever libtool instructs the compiler to generate a PIC
35、 object, it also defines the preprocessor symbol, PIC, so that assembly code can be aware of whether it will reside in a PIC object or not.Typically, as libtool is compiling sources, it will generate a .lo object, as PIC, and a .o object, as non-PIC, and then it will use the appropriate one of the p
36、air when linking executables and libraries of various sorts. On architectures where there is no distinction, the .lo file is just a soft link to the .o file.In practice, you can link PIC objects into a static archive for a small overhead in execution and load speed, and often you can similarly link
37、non -PIC objects into shared archives.When you use position -independent code, relocatable references are generated as an indirection that use data in the shared objects data segment. The text segment code remains read -only, and all relocation updates are applied to corresponding entries within the
38、 data segment.If a shared object is built from code that is not position -independent, the text segment will usually require a large number of relocations to be performed at runtime. Although the runtime linker is equipped to handle this, the system overhead this creates can cause serious performanc
39、e degradation.You can identify a shared object that requires relocations against its text segment using tools such as readelf -d foo and inspect the output for any TEXTREL entry. The value of the TEXTREL entry is irrelevant. Its presence in a shared object indicates that text relocations exist.A.7.
40、ld.so/lib/ld.so 是系統(tǒng)的動態(tài)庫加載器,屬于 Glibc 編譯生成的,與系統(tǒng)平臺密切相關(guān)。加載目標 代碼 涉及的內(nèi)容很多,但是這里主要圍繞 ld.so 的動態(tài)庫搜索過程,做全面的解釋。ld.so 在加載動態(tài)庫的時候,分先后順序,按以下六步搜索:1.可執(zhí)行文件自身的動態(tài)段(.dynamic section )中DT_NEED入口中包含的路徑。首先應(yīng)該了解到,每個執(zhí)行文件的數(shù)據(jù)是按照段來存儲的,有代碼段,數(shù)據(jù)段,BSS段等。那么 這里的動態(tài)段也是其中的一部分。我們借助 readelf 命令來查看這部分信息:root Benson libtest# readelf -d mainTag
41、 Type 0x00000001 (NEEDED) 0x00000001 (NEEDED) 0x0000000c (INIT) 0x0000000d (FINI) 0x00000004 (HASH) 0x001000005 (STRTAB) 0x00000006 (SYMTAB) 0x0000000a (STRSZ) 0x0000000b (SYMENT) 0x00000015 (DEBUG) 0x00000003 (PLTGOT) 0x00000002 (PLTRELSZ) 0x00000014 (PLTREL) 0x00000017 (JMPREL) 0x00000011 (REL) 0x
42、00000012 (RELSZ) 0x00000013 (RELENT) 0x6ffffffe (VERNEED) 0x6fffffff (VERNEEDNUM) 0x6ffffff0 (VERSYM)Name/ValueShared library: liba.soShared library: libc.so.60x80483400x80484e40x80481280x80482400x8048170172 (bytes)16 (bytes)0x00x80495fc16 (bytes)REL0x80483300x80483288 (bytes)8 (bytes)0x804830810x80
43、482ec0x00000000 (NULL) 0x0readelf命令,能夠查看ELF格式的文件的所有信息,在這里先不詳細介紹。對于上邊顯示的信息我們注意前兩行,類型是 NEEDED后便對應(yīng)的是內(nèi)容,這些就是DT_NEED部分的內(nèi)容。而內(nèi)容部分的 liba.so 和 libc.so.6 是沒有路徑信息的。所以 ld.so 不能根據(jù)這里的信息加 載 liba.so 庫。但如果使用如下的命令生成 main 程序:root Benson libtest# gcc -o main main.o ./liba.soroot Benson libtest# readelf -d main0x0000000
44、1 (NEEDED) 0x00000001 (NEEDED) 0x0000000c (INIT) 0x0000000d (FINI) 0x00000004 (HASH) 0x001000005 (STRTAB) 0x00000006 (SYMTAB) 0x0000000a (STRSZ)Shared library: ./liba.soShared library: libc.so.60x80483400x80484e40x80481280x80482400x8048170172 (bytes)0x0000000b (SYMENT)16 (bytes)0x00000015 (DEBUG)0x00x00000003 (PLTGOT)0x80495fc0x00000002 (PLTRELSZ)16 (bytes)0x00000014 (PLTREL)REL0x00000017 (JMPREL)0x80483300x00000011 (REL)0x80483280x00000012 (RELSZ)8 (bytes)0x00000013 (RELENT)8 (bytes)0x6ffffffe (VERNEED)0x80483080x6fffffff (VERNEE
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 汝州職業(yè)技術(shù)學(xué)院《酒店應(yīng)用英語高級》2023-2024學(xué)年第一學(xué)期期末試卷
- 2025年浙江嘉興市三水灣中學(xué)招聘筆試參考題庫含答案解析
- 2025年寧波市鄞州區(qū)國有企業(yè)招聘筆試參考題庫含答案解析
- 2025年南網(wǎng)廣州電力交易中心招聘筆試參考題庫含答案解析
- 2024版員工正式勞動合同
- 2024版家居加盟店合同范本3篇
- 2024版上海個人租房合同范文
- 二零二五年度公司員工股權(quán)激勵方案合同6篇
- 二零二五年度活動房空調(diào)租賃與綠色環(huán)保認證服務(wù)合同9篇
- 二零二五年度班主任新手帶教與教學(xué)輔導(dǎo)合同3篇
- 江西省商品混凝土企業(yè)名錄
- 毒理學(xué)第三章化學(xué)毒物在體內(nèi)的生物轉(zhuǎn)運和生物轉(zhuǎn)化
- 企業(yè)年會活動抽獎滾動抽獎經(jīng)典創(chuàng)意高端模板課件
- 技術(shù)資料檢查評分表
- 國際森林日森林防火教育宣傳主題班會PPT模板
- 軸聯(lián)軸器離合器解析課件
- 一年級上學(xué)期語文期末試卷分析一年級上冊語文試卷
- C4支持學(xué)生創(chuàng)造性學(xué)習與表達作業(yè)1-設(shè)計方案
- 藥廠質(zhì)量管理部QA人員崗位設(shè)置表
- Q∕SY 01330-2020 井下作業(yè)現(xiàn)場監(jiān)督規(guī)范
- 醫(yī)院關(guān)于不合理醫(yī)療檢查專項治理自查自查自糾總結(jié)
評論
0/150
提交評論