DLL expertise

Is there a book or consolidated web resource that provides advanced details of DLLs Some of the things I want to study in depth:

1) binding an executable to a specific version of DLL (that is, to resolve the addresses of imported functions at compile-time).

2) pre-mapping of DLLs to different fixed addresses.

3) relocating DLL code, as it is loaded from disk, can make it potentially non-shareable between processes. What exactly causes this

4) Can a DLL referenced in C++ code with #import be either explicitly or implicitly linked, or does it only permit implicit

5) In C++, when is it appropriate to use "#import"

My own guess, regarding question 5, is that #import has two purposes:

1) To allow the registry to provide a DLL path, in cases where "generically" knowing the path would otherwise be awkward. I think this applies only to COM server DLLs.

2) To access DLLs that install as part of a 3rd party application - where that 3rd party application provided embedded DLL type library info rather than providing a header file. If these are not COM servers, and thus not recorded in the registry, then a path must be provided to the #import statement.

Anyway, back to my original point, is there a book that serves as a "Mecca" of knowledge on DLLs




Answer this question

DLL expertise

  • Stuart McHugh

    Thanks for the reply! I'm not too worried about a 1997 date, since I don't believe DLL functionality has changed since then. But having looked up this book, I see it has a "newer" edition:
    http://www.amazon.com/gp/product/1572319968/sr=8-1/qid=1155503121/ref=pd_bbs_1/103-3391931-8015043 ie=UTF8

    Its pricey, but I think I just might. :)

    To your specific answers:

    1) The reason why I asked this question about resolving addresses at compile time, is because of a wikipedia comment which reads "It is also possible to bind an executable to a specific version of DLL, that is, to resolve the addresses of imported functions at compile-time. For bound imports, the linker saves the timestamp and checksum of the DLL to which the import is bound". If wikipedia is correct, then there is a way to do this.
    http://en.wikipedia.org/wiki/Dynamic_Link_Library

    2) For the commands / tools...cool, thanks. But I'm particularly after the strategy used in choosing a new base. For example, what circumstance would force me to need this feature And once I have been forced into using this feature, what is the new address I should choose There must be some kind of strategy for this...and if that book provides that info, all the more reason I probably should go get it. :)
    Also, I have the impression there is a way to rebase a DLL at load time, not just at build time (or post-build with rebase). Yes

    3) My understanding is that normally no virtual pages are written to disk for DLL code segments. Instead, the DLL file itself is treated as the virtual page, and so the DLL code segment is "reloaded" from the original DLL, each time a page fault for that DLL code occurs. But taking what you've said, I gather that once a particular process has load-time rebased a given DLL, no other process will be aware that this has occurred, and so the others must continue to use the original load location. Also, if I read into your answer, it appears that after you've done a load-time "rebase," that it is no longer possible for the original DLL to be used as the on-disk virtual page. That is, a load-time rebased DLL must now be given its own on-disk virtual page.

    4) I recently had to add "include directory" path information to a VC++ project, so that the "#import" could find msado15.dll. Not being familiar with "#import," it still struck me as weird, because I figured the compiler would know the location of the DLL by consulting the registry, rather than needing my explicit help. And yes, I had made sure to run regsvr32 on that DLL, to be sure it was set to go...but bottom line, you are confirming that "#import" only applies to COM...



  • Jonathan Cran

    The original book I read is this one. But it is dated (1997).

    1: when you link the DLL, the linker creates an import library (mydll.lib). You'd link that library when you build your EXE to explicitly link the DLL. Addresses of DLL exports are *not* resolved at compile time, it happens at EXE load time.

    2: Project + options, Linker, Advanced, Base Address option. You can change it after building with the EditBin.exe or Rebase.exe utilities.

    3: When the DLL needs to be moved from its requested base address, the loader patches the absolute addresses in the DLL code. That makes the DLL image no longer match the executable image as backed-up in the paging file and the virtual memory pages can no longer be shared between processes.

    4: You'd use #import only on COM modules to automatically generate wrappers for the interfaces defined in the tool library.

    5: To make it easy to use COM interfaces.


  • BortNE24

    Hi Mystagogue,

    I also need to know answers to your queries.

    Sorry to say but I am not clear about the reply given by nobugz.

    Did you got answer to your queries especially number 1 &3 .

    If yes ,please share

    Also need to know where do linker store he .lib files generated for linked dll

    regards

     


  • Caioshin

    Expanding a bit on 1) and 3):

    The Platform SDK has a utility named Bind.exe; it can patch the executable image to replace indirect jumps through a DLL's export table by absolute jumps. Here's an article that describes what is done. Here's another. Bind.exe is not distributed with VS200x but is available if you download the Platform SDK separately. Don't use it unless you're 100% sure you'll never have to update the DLL. If you do, the .exe will just fail at startup.

    Every Windows program will use Kernel32.dll. This DLL is however only loaded once into physical memory and every process' virtual memory pages for kernel32.dll are mapped to that same physical memory. If those physical pages ever get swapped out, Windows will reload them directly from the Kernel32.dll file. The MapViewOfFile() API function exposes that kernel functionality to application programs.

    When a DLL can't be loaded at its base address, as set by the linker, the Windows loader patches up the DLL executable image to make it runnable at the new base address. For one, the patched virtual memory pages now no longer match the memory pages of another process that did happen to be able to load the DLL at its base address. Therefore, the physical memory pages can no longer be shared and the virtual memory pages must now map to dedicated physical pages with the patched DLL image. For another, when those pages get swapped out, they can't be reloaded from the DLL image file so the pages must be backed up in the swap file.


  • Vedratna

    No, that's not the book I was talking about. That one is ancient (Windows 3.51 vintage) and out of print. $178.75, wow, my book-case is getting valuable.

    1) You're right. That was a brain cell that went dormant a long time ago. It doesn't make a lot of sense to me to make it difficult to update a DLL. The performance improvement is only measured in microseconds. Most of all, this feature is not available in the VS200x IDE.

    2) The diagnostic is simple, you'll see a message from the Windows loader in the debugger output (looks like "LDR: blablabla") when it is forced to move a DLL. I typically start thinking about it near the end of a large project and start picking base addresses with lots of room for growth. There's a lot to choose from, at least in my projects. Pick them towards the bottom, Microsoft DLLs always use high load addresses (just below 0x7ffffff). Your .exe's start address is 0x0040000

    3) Right. Not sure what happens if the DLL gets rebased, it probably now takes up pages in the swap file.

    4) I always just specify the full path to the .dll in the #import statement. I quite prefer having to specify path, there's enough misery with COM component registration. And it makes sense to me that you should be able to compile code to use a COM component without it having to be installed on the computer doing the compiling.



  • DLL expertise