【发布时间】:2015-03-20 07:04:11
【问题描述】:
我在 Windows 上读到,可执行文件的模块映射到相同的地址空间。 我不明白为什么
typedef int (__stdcall *fptr)();
int main(void)
{
HINSTANCE h;
fptr f;
std::stringstream oss;
h = LoadLibrary("test.dll");
if (! h)
return EXIT_FAILURE;
f = (fptr)GetProcAddress(h, "function");
if (! f)
return EXIT_FAILURE;
oss << (DWORD *)f;
std::cout <<"main: "<< oss << std::endl;
_getch();
return EXIT_SUCCESS;
}
和
extern "C" {
void __declspec(dllexport) function() {
return ;
}
}
int main(HMODULE m)
{
std::stringstream oss;
oss << (DWORD *)function;
std::cout << "dll: " << oss << std::endl;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
main(hModule);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
产生这个结果:
> "test.exe"
dll: 007BFDB8
main: 0039F944
另外,地址 007BFD88 不能从主进程访问。 为什么这两个地址不同?
【问题讨论】:
-
由 MSVC++ 链接器实现并在调试版本中使用的增量链接是一种解释。您在 DLL 中获得的地址是跳转到实际函数的 JMP 指令的地址。使用 Release 版本再试一次。
-
非常感谢,这正是我想要的。你解决了我的问题。
-
@HansPassant 如果完全相同的函数由于某些代码生成/链接约定而具有不同的地址,则 C++ 编译器将不符合标准。
-
嗯,让我参考描述模块应该如何表现的 C++ 标准。
标签: c++ windows api dll module