January 11th, 2013

Understanding errors in classical linking: The delay-load catch-22

Wrapping up our week of understanding the classical model for linking, we’ll put together all the little pieces we’ve learned this week to puzzle out a linker problem: The delay-load catch-22.

You do some code cleanup, then rebuild your project, and you get

LNK4199: /DELAYLOAD:SHLWAPI ignored; no imports found from SHLWAPI

What does this error mean?

It means that you passed a DLL via the /DELAYLOAD command line switch which your program doesn’t actually use, so the linker is saying, “Um, you said to treat this DLL special, but I don’t see that DLL.”

“Oh, right,” you say to yourself. “I got rid of a call to Hash­String, and that was probably the last remaining function with a dependency on SHLWAPI.DLL. The linker is complaining that I asked to delay-load a DLL that I wasn’t even loading!”

You fix the problem by deleting SHLWAPI.DLL from the /DELAYLOAD list, and removing SHLWAPI.LIB from the list of import libararies. And then you rebuild, and now you get

LNK2019: unresolved external ‘__imp__HashData’ referenced in function ‘HashString’

“Wait a second, I stopped calling that function. What’s going on!”

What’s going on is that the Hash­String function got taken along for the ride by another function. The order of operations in the linker is

  • Perform classical linking
  • Perform nonclassical post-processing
    • Remove unused functions (if requested)
    • Apply DELAYLOAD (if requested)

The linker doesn’t have a crystal ball and say, “I see that in the future, the ‘remove unused functions’ step is going to delete this function, so I can throw it away right now during the classical linking phase.”

You have a few solutions available to you.

If you can modify the library, you can split the Hash­String function out so that it doesn’t come along for the ride.

If you cannot modify the library, then you’ll have to use the /IGNORE flag to explicitly ignore the warning.

Exercise: Another option is to leave SHLWAPI.LIB in the list of import libraries, but remove it from the DELAYLOAD list. Why is this a dangerous option? What can you do to make it less dangerous?

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.