2

In C++, if you try to get a function pointer of a Windows API function, that pointer points to the same address you would get if you used GetProcAddress on the name of that function and it's respective module. For example:

&MessageBoxA == GetProcAddress("User32.dll", "MessageBoxA");

would be true. However, in Delphi, that is not the case. This code:

@MessageBoxA = GetProcAddress('User32.dll', 'MessageBoxA');

Would not be true, and in my test, @MessageBoxA was 0x0040bd18 while the equivalent GetProcAdress returned what the test's C++ counterpart did, 0x7550fd1e.

So now for my question: why?

animuson
  • 53,861
  • 28
  • 137
  • 147
みっつ
  • 23
  • 2

1 Answers1

6

The address with the 0x004.. is the address of the declaration of the imported api function (in windows.pas for MessageBoxA) to have it statically loaded, hence it will of course reside in the executable image (which have a base address of 0x00400000 by default). The actual function called is in the image of the library loaded to the memory of that function resides in. You can get the image base of the library with GetModuleHandle. In your case it will probably be something with 0x75... With the C++ test, you're probably linking with the runtime library, so the function is dynamically loaded anyway.

Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
  • I don't think this answer fully covers why Delphi programs have stubs for imported DLL functions and C programs don't. – Rob Kennedy Feb 28 '11 at 05:41
  • @Rob - Isn't that why Delphi does not require .lib files? C programs have the definitions in header files and addresses of the imported functions in the .lib file which is linked to the idata section to get resolved by the Win32 loader? – Sertac Akyuz Feb 28 '11 at 08:07
  • @SertacAkyuz No it is not. Linkage is different for most C++ compilers. They don't use thunks and the addresses are fixed up by the loaded. – David Heffernan Dec 06 '13 at 11:58
  • @David - I'm not sure what you say contradicts what I said. – Sertac Akyuz Dec 06 '13 at 12:15
  • @Sertac OK, but it's not really about .lib files. It's perfectly possible to link without .lib files, and without thunks. It's compiler choice. C++ linkers could go either way. All an import .lib file provides is a function name (in case exported name differs from import name) and a dll name. So too could Delphi. Delphi could avoid thunks if the devs had made that choice. Thunks reduce exe size at the cost of an extra layer of indirection. – David Heffernan Dec 06 '13 at 13:10
  • @David - Thanks, I was under the impression that they require linking to import libs for static loading. – Sertac Akyuz Dec 06 '13 at 13:44
  • @Sertac No. It's not required. It's how it tends to be done. Much of that is historical. GCC can link statically to a dll with no lib file. You supply the dll itself and the linker works it out. Remember also that C++ lang has no equivalent to Delphi's external. So that info comes from outside the source. – David Heffernan Dec 06 '13 at 13:48