[初]静态链接和动态链接的一些问题

    技术2022-05-11  93

    静态链接和动态链接的一些问题

     

    料:

    1 <<c&c++深度探索>>

    2 http://www.graphics.net.cn/document/vc/003/348.asp

     

     

    要生成动态链接?

        静态链接有两个特点:

        l接后生的可行文件包含了所有需要用的函的代,因此占用磁

    间较大;

        2如果有多(用相同)程在存中间时运行,存中就存有多

    相同的,因此占用存空间较多。

        动态链接就是了解决这问题生的技名思动态链接的意思就是在程

    序装存的候才正把码链进来确定它们的地址,且就算有多

    行,存也只存在一

     

     

    Linux如何生成动态库

    /* Example code   main.c */

    int fun(void);

    int main(void)

    {

          fun():

          return 0;

    }

    /* Example code   fun.c */

    int fun(void)

    {

          return 0;

    }

     

     

     

    里有两个C文件,其中,我要把包含fun的那文件编译PIC,放到动态库里去:

    $gcc -c -fPIC fun.c

    $gcc -shared -o libfun.so fun.o  <-----就是行代

    然后:

    $gcc main.c -L. –lfun

    生成a.out

     

    这时成功生成可行文件,不,要使系使用动态库,必须让知道放置动态库的位置,

    简单法是LD_LIBRARY_PATH量(在window底下是LIBRARY_PATH

     

    动态库两个关概?

       1静态绑(static blnding)

        使用静态绑定的程序在一存的候,入程序就把程序所有用到的

    动态的地址算出、确定下这种方式使程序刚运的初始化时间较长,不

    但完成动态,程序的行速度就很快。

        2动态绑(dynamic binding)

        使用这种方式的程序不在一始就完成动态链接,而是直到动态库

    入程序才(用的那部分)动态逻辑地址,然后等到某个时候,程

    序又需要用另外某块动态码时入程序才又去部分代逻辑地址。所以,

    这种方式侄程序初始化时间较短,但行期的性能比不上静态绑定的程序。

     

     

    Linux下如何生成静态库

    两个命令gccar

    gcc -c filename1.c

    ar -r libabc.a filename1.o

     

    /* Example code 13-01, file name: 1301.c */

     

    extern int global;

     

    void f(void);

     

    int main(void)

    {

        f();

        ++global;

        return 0;

    }

    /* Example code 13-01a, file name: 1301a.c */

     

    extern void g(void);

    int global = 0;

    void f(void) {

         printf("in the f()");

         g();

    };

    /* Example code 13-01b, file name: 1301b.c */

     

    static int local = 1;

    void g(void) { --local; }

     

    1

    gcc –c  1301a.c 1301b.c

    生成  1301a.o 1301b.o

     

    2

    ar rc libtest.a 1301a.o 1301b.o

    生成 libtest.a  (静态库文件名通常是libxxx.a)

     

    3

    gcc 1301.c –L. -ltest

    生成 a.exe  (在windows平台自生成a.exe,unix平台生成a.out

     

     

    Window下的动态链接技?

    SDK笔记 - DLL 1. 动态链接之含 用程序常使用所静态链的方法,即文件(.obj)数库(.lib)以及已编译源文件(.res)接到一起,形成一行文件(.exe)。使用静态链,可行文件需要使用的各源都已包含到文件中。这样做的缺点是于多程序都使用的相同函源要重复链接到exe文件中,使程序大、占用存增加。动态链一些公用的函组织动态链文件(.dll)需要使用dll中的函源的程序启动时(准确的是初始化),系统将该dll映射到程的虚拟地址空、增加dll的引用计数值,然后当实际使用到dll操作系将该dll存;如果使用dll的所有程序都已束,统将该库从内存中移除。使用同一dll的各个进程在共享dll的代,但是dll中的各有一(然也有在dll中共享据的方法)动态链中可以定义两种出函部函出函可以被其他模块调用,部函只能被动态链本身用。动态链也可以据,但据通常只被自己的函所使用。 2. 动态链接的节约内存;使用程序单独修改动态链而不必与应用程序重新接;可方便实现(比如用VC++写个dll,然后在VB)将资源打包;可在用程序共享 →...... 3. 展名 动态链展名是dll,其他如exe,drv,fon也可作为扩展名,但只有展名dll动态链才能被Windows动载入。如果使用其它扩展名的动态链则调动态链的程序中必使用LoadLibraryLoadLibraryEx动态链 4. SDK建一个简单dll文件 VC++选择新建一Win32 Dynamic-Link Library。需要建立一c/c++ head file和一c/c++ source file加入工程。文件中为输出函明,源文件中DllMain出函的定。下面是一简单的例子。 //dlldemo.h #ifdef __cplusplus #define EXPORT extern "C" __declspec(dllexport) #else #define EXPORT __declspec(dllexport) #endif EXPORT void CALLBACK DllFoo(void) ; //dlldemo.c #include <windows.h> #include "dlldemo.h" int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) { return TRUE ; } EXPORT void CALLBACK DllFoo(void) { MessageBox(NULL,TEXT("This function is exported from a DLL"),TEXT("DllFoo"),MB_OK) ; return ; } 文件预处理中的__declspec是微增加的“C储属”(C Extended Storage-Class Attributes)指明一个给出的例被存储为特定的储属性,可以thread,naked,dllimportdllexport. [MSDN原文:The extended attribute syntax for specifying storage-class information uses the __declspec keyword, which specifies that an instance of a given type is to be stored with a Microsoft-specific storage-class attribute (thread, naked, dllimport, or dllexport).] 出函指明CALLBACK DllMaindll的入口点函。也可以不写它DllMain返回TRUE,否统将终止程序并弹出一启动程序对话框。 编译链接后,得到动态链文件dlldemo.dll文件dlldemo.lib 5.使用dll两种方式 方法一: load-time dynamic linking 在要dll用程序dll文件(import library.lib文件)包含去。具体的做 法是在源文件开头加一句#include ,然后就可以在源文件中dlldemo.dll中的出文件了。 方法二: run-time dynamic linking 不必在包含文件,而是在源程序中使用LoadLibraryLoadLibraryEx动态dll 主要步骤为(demodll.dll): 1) typedef原型和定 typedef void (CALLBACK* DllFooType)(void) ; DllFooType pfnDllFoo = NULL ; 2) 使用LoadLibrarydll保存dll例句柄 HINSTANCE dllHandle = NULL ; ... dllHandle = LoadLibrary(TEXT("dlldemo.dll")); 3) 使用GetProcAddress得到dll中函的指 pfnDllFoo = (DllFooType)GetProcAddress(dllHandle,TEXT("DllFoo")) ; 注意GetProcAddress返回的指须转特定型的函 4)检验,如果不 if(pfnDllFoo!=NULL) DllFoo() ; 5)使用FreeLibrarydll FreeLibrary(dllHandle) ; 使用run-time dynamic linking ,但有的好(下面讨论)MSDN中有一篇文章DLLs the Dynamic Way讨论使用c的宏建一pDll完成以上复杂的操作,使用只需定个类继承自pDll 对类和函使用宏。 以上两种方法都要求用程序能找到dll文件,Windows按以下dll文件: 1)用程序所在目 2)前目 3)Windows 9x : System Windows 2000/NT : System32 4)Windows 2000/NTSystem 5)Windows所在目 6)path中的路 如果系不能找到dll文件,将结dll并弹出一启动程序对话框,告诉你找 不到所需的dll文件-XXX.dll” 6 使用动态链(Run-Time Dynamic Linking)有什 如果使用动态链(Load-Time Dynamic Linking)dll文件用此dll的程序不能行,你将会看到一启动程序对话框。而如果在时载dll有机会处这个错误,至少可以比束程序。 如果dll了,使用load-time dynamic linking的程序可能会终止,而使用run-time dynamic linking 的程序只有当调用的函在新的dll中不存在 7 使用纯资dll 一般只在其c文件中空的DllMain,然后向工程中源,最后编译为dll文件。纯资dll有任何出函,因此不生成.lib文件,所以必LoadLibrary入。 8 dll中使用共享(摘自programming windows) // shared memory section (requires /SECTION:shared,RWS in link options) #pragma data_seg ("shared") int iTotal = 0 ; WCHAR szStrings [MAX_STRINGS][MAX_LENGTH + 1] = { '/0' } ; #pragma data_seg () #pragma comment(linker,"/SECTION:shared,RWS") 第一#pragma述建立料段,里命名shared可以将这段命名任何一个您的名字。在里的#pragma述之后的所有初始化了的变数都放在shared料段中。第二#pragma示段的束。对变数进专门的初始化是很重要的,否则编译它们放在普通的未初始化料段中而不是放在shared中。 连结器必知道有一shared」共享料段。在「Project Settings对话块选择Link标签中「STRLIB在「Project Options位(在ReleaseDebug定中均可),包含下面的连结叙述: /SECTION:shared,RWS 字母RWS表示段具有和共用性。或者,也可以直接用DLL原始指定连结选项,就像我STRLIB.C #pragma comment(linker,"/SECTION:shared,RWS") the end 料:http://www.graphics.net.cn/document/vc/003/348.asp

     

     

    动态链接库的一些名词

    参考资料:

    http://blog.csdn.net/gofishing/archive/2006/05/09/715052.aspx

    1、什么是动态链接库?它不是应用程序,不能直接运行,也不能接收消息。dll是一系列函数的集合,可以简单理解为把一些函数放到了一个文件里面,这些函数可以被其它程序和dll调用。一个dll可以同时被几个程序或其它dll调用,这应该是它的特点。2、windows api与dllwindows api中的所有函数均包含在dll中,当然不会是一个dll。其中最为重要的3个windows api的dll文件是:Kernel32.dll 主要是管理内存、进程和线程的函数的集合;User32.dll 执行用户界面的任务的函数(比如:窗口的创建销毁放大缩小、消息的传递等等与用户相关的操作);GDI32.dll 包含用于画图和显示文本的各个函数;3、静态库和动态库静态库是把程序运行时需要使用的函数编译在一个二进制文件中,扩展名为.lib。当程序link时把静态库中的二进制数据和程序其它数据放到一起。程序运行时不在需要lib和dll文件的支持。这样做的坏处是开发出来的程序占用磁盘空间较大。特别是windows系统中本来就有或很多程序运行都需要的函数完全没有必要每次开发程序时都要使用各自的静态库。而动态库在开发时仅是把dll中的函数名和参数放到应用程序中,应用程序运行时根据函数名和参数调用dll中的函数来运行,这样操作系统中的应用程序可以同时使用同一个dll。可以有效地节省硬盘空间,当然这样做使得程序设计更有层次。也有利于软件工程师的分工和信息安全。4、引入库和动态库引入库和动态库是成对出现的,在编译dll的时候会同时产生一个引入库,扩展名为lib。lib中仅含有dll中的函数名和参数,真正的函数体在动态库中。两个的关系大概相当于.h和.cpp文件之间的关系。在编写程序的过程中5、引入库和静态库引入库和静态库的扩展名均为*.lib,但是引入库仅包含一些函数名和参数信息,没有函数体,是为调用动态库服务的,它和动态库的关系相当于.h文件和.cpp文件之间的关系;


    最新回复(0)