【问题标题】:Addresses of Delphi and C++ WinAPI functions differ when they shouldn'tDelphi 和 C++ WinAPI 函数的地址不应该不同
【发布时间】:2011-02-28 01:13:57
【问题描述】:

在 C++ 中,如果您尝试获取 Windows API 函数的函数指针,则该指针指向的地址与您在该函数的名称上使用 GetProcAddress 时获得的地址相同,并且它是相应的模块。例如:

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

应该是true。但是,在 Delphi 中,情况并非如此。这段代码:

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

不会true,在我的测试中,@MessageBoxA0x0040bd18,而等效的 GetProcAdress 返回测试的 C++ 对应项 0x7550fd1e

那么现在我的问题是:为什么?

【问题讨论】:

    标签: delphi winapi delphi-2010 getprocaddress


    【解决方案1】:

    带有 0x004.. 的地址是导入的 api 函数的声明地址(在 windows.pas 中为 MessageBoxA)拥有它 statically loaded,因此它当然会驻留在可执行映像中(其中默认情况下,基地址为 0x00400000)。实际调用的函数位于加载到该函数所在内存的库的映像中。您可以使用GetModuleHandle 获取库的映像库。在您的情况下,它可能是 0x75... 对于 C++ 测试,您可能正在链接运行时库,因此无论如何该函数都是动态加载的。

    【讨论】:

    • 我不认为这个答案完全涵盖了为什么 Delphi 程序有用于导入的 DLL 函数的存根而 C 程序没有。
    • @Rob - 这不是 Delphi 不需要 .lib 文件的原因吗? C 程序在头文件中有定义,在.lib 文件中有导入函数的地址,该文件链接到 idata 部分以由 Win32 加载程序解析?
    • @SertacAkyuz 不,不是。大多数 C++ 编译器的链接是不同的。它们不使用 thunk,并且地址由加载的固定。
    • @David - 我不确定你说的是否与我说的相矛盾。
    • @Sertac 好的,但这与 .lib 文件无关。完全可以在没有 .lib 文件且没有 thunk 的情况下进行链接。这是编译器的选择。 C++ 链接器可以采用任何一种方式。导入 .lib 文件只提供一个函数名称(以防导出名称与导入名称不同)和一个 dll 名称。德尔福也可以。如果开发人员做出了这样的选择,Delphi 可以避免重击。 Thunks 以额外的间接层为代价来减小 exe 的大小。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 2012-05-27
    • 2022-11-29
    • 2022-07-06
    相关资源
    最近更新 更多