Я прочитал, что на окнах модули исполняемого файла отображаются в одном и том же адресном пространстве. я не понимаю, почемуНа окнах, почему существуют разные адреса для того же модуля?
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++ и используемое в сборке Debug, является одним из объяснений. Адрес, который вы получаете в вашей DLL, является адресом инструкции JMP, которая перескакивает на реальную функцию. Повторите попытку с помощью сборки Release. –
Большое спасибо, это именно то, что я искал. Вы решили мою проблему. – antoine
@HansPassant, если точно такая же функция будет иметь разные адреса из-за некоторых соглашений генерации/компоновки кода, компилятор C++ будет несовместим со стандартом. – Christophe