C/C++ How Does Dynamic Linking Work On Different Platforms?

后端 未结 9 1072
渐次进展
渐次进展 2020-12-24 03:20

How does dynamic linking work generally?

On Windows (LoadLibrary), you need a .dll to call at runtime, but at link time, you need to provide a corresponding .lib fi

相关标签:
9条回答
  • 2020-12-24 03:52

    To answer your questions one by one:

    • Dynamic linking defers part of the linking process to runtime. It can be used in two ways: implicitly and explicitly. Implicitly, the static linker will insert information into the executable which will cause the library to load and resolve the necessary symbols. Explicitly, you must call LoadLibrary or dlopen manually, and then GetProcAddress/dlsym for each symbol you need to use. Implicit loading is used for things like the system library, where the implementation will depend on the version of the system, but the interface is guaranteed. Explicit loading is used for things like plug-ins, where the library to be loaded will be determined at runtime.

    • The .lib file is only necessary for implicit loading. It contains the information that the library actually provides this symbol, so the linker won't complain that the symbol is undefined, and it tells the linker in what library the symbols are located, so it can insert the necessary information to cause this library to automatically be loaded. All the header files tell the compiler is that the symbols will exist, somewhere; the linker needs the .lib to know where.

    • Under Unix, all of the information is extracted from the .so. Why Windows requires two separate files, rather than putting all of the information in one file, I don't know; it's actually duplicating most of the information, since the information needed in the .lib is also needed in the .dll. (Perhaps licensing issues. You can distribute your program with the .dll, but no one can link against the libraries unless they have a .lib.)

    The main thing to retain is that if you want implicit loading, you have to provide the linker with the appropriate information, either with a .lib or a .so file, so that it can insert that information into the executable. And that if you want explicit loading, you can't refer to any of the symbols in the library directly; you have to call GetProcAddress/dlsym to get their addresses yourself (and do some funny casting to use them).

    0 讨论(0)
  • 2020-12-24 03:56

    Linux also requires to link, but instead against a .Lib library it needs to link to the dynamic linker /lib/ld-linux.so.2, but this usually happens behind the scenes when using GCC (however if using an assembler you do need to specify it manually).

    Both approaches, either the Windows .LIB approach or the Linux dynamic linker linking approach, are considered in reality as static linking. There is, however, a difference that in Windows part of the work is done at link time although it still has work at load time (I am not sure, but I think that the .LIB file is merely for the linker to know the physical library name, the symbols however are only resolved at load time), while in Linux everything besides linking to the dynamic linker happen at load time.

    Dynamic linking is in general referring to open manually the DLL file at runtime (such as using LoadLinrary()), in which case the burden is entirely on the programmer.

    0 讨论(0)
  • 2020-12-24 04:02

    In shared library, such as .dll .dylib and .so, there is some information about symbol's name and address, like this:

    ------------------------------------
    | symbol's name | symbol's address |
    |----------------------------------|
    | Foo           | 0x12341234       |
    | Bar           | 0xabcdabcd       |
    ------------------------------------
    

    And the load function, such as LoadLibrary and dlopen, loads shared library and make it available to use.

    GetProcAddress and dlsym find you symbol's address. For example:

    HMODULE shared_lib = LoadLibrary("asdf.dll");
    void *symbol = GetProcAddress("Foo");
    // symbol is 0x12341234
    

    In windows, there is .lib file to use .dll. When you link to this .lib file, you don't need to call LoadLibrary and GetProcAddress, and just use shared library's function as if they're "normal" functions. How can it work?

    In fact, the .lib contains an import information. It's like that:

    void *Foo; // please put the address of Foo there
    void *Bar; // please put the address of Bar there
    

    When the operating system loads your program (strictly speaking, your module), operating system performs LoadLibrary and GetProcAddress automatically.

    And if you write code such as Foo();, compiler convert it into (*Foo)(); automatically. So you can use them as if they're "normal" functions.

    0 讨论(0)
提交回复
热议问题