Нарушение на достъпа при извикване на статична библиотека

Като разширение на въпрос MSVC неразрешени изпълними файлове за свързване на външни символи. A съдържа и клас P с две функции-членове F и G, а също така съдържа глобален P MyP. Опитвам се да извикам функции MyP.F от изпълним файл T. Най-накрая преминах частта за свързване, но сега се проваля по време на изпълнение с изключение.

A.cpp

 struct P {
     void F();
     void G();
 } MyP;

 P::F() {
 }
 P::G() {
 }
 int main() {
     MyP.F();
     MyP.G();
 }

T.cpp

struct P {
     void F();
     void G();
} MyP;

int main() {
    MyP.F();
    MyP.G();
}

Мога да поставя точка на прекъсване в T на реда, където извиква F във Visual Studio 2008, но когато натисна бутона за влизане или преминаване, получавам изключение First-chance exception at 0xfe5ca589 in A.exe: 0xC0000005: Access reading location 0xfe5ca589. Когато гледам стека на повикванията, той показва

fe5ca589()
A.exe!G() + 0x60a6 байта
[Рамките по-долу може да са неправилни и/или липсващи, няма заредени символи за A.exe]

И двата проекта са част от едно и също решение на Visual Studio и A е правилно зададен като зависимост за T и изглежда се свързва правилно, но не мога да вляза в него. Някой има ли представа как да накара Visual Studio да зареди символите за A, за да мога да вляза в него и да намеря грешката? (Или ако нещо е свързано смешно, което причинява грешката?)


person Mooing Duck    schedule 15.09.2011    source източник
comment
stackoverflow.com/ въпроси/6283482/   -  person Ben Voigt    schedule 16.09.2011


Отговори (1)


Изпълнимите файлове нямат метаданни, позволяващи да бъдат заредени на алтернативен адрес и A.EXE не може да се зареди в T.EXE на желания адрес, защото кодът на T.EXE вече е там.

Може да можете да заобиколите това, като промените адреса за зареждане по подразбиране на A.EXE (когато го компилирате, това е опция за свързване), но правилното решение е да използвате DLL. (Потвърдено, не, не можете)

Предвидени са експорти от .EXE файлове, за да се позволи DLL на приставките да извикват функции в основното приложение. Те не са предназначени да позволяват зареждането на .EXE сякаш е DLL.

person Ben Voigt    schedule 15.09.2011
comment
О, това не е добре. Работя върху това около месец на работа и всичко, от което се нуждая от A, е един клас. Така че предполагам, че трябва да обясня на шефовете си, че това, което исках, не се прави толкова лесно, колкото си мислех, и трябва да добавим A_alt проект като статична библиотека, към която T да се свърже. - person Mooing Duck; 16.09.2011
comment
И Windows Linker не забеляза, че това ще бъде проблем? Лош Microsoft. - person Mooing Duck; 16.09.2011
comment
@Mooing: За повече информация потърсете това обяснение на PE формата за преместване. Може да е възможно да принудите линкера да излъчва данни за преместване в A.EXE или да промените адреса за зареждане на T.EXE, така че A.EXE да не се нуждае от коригиране, но определено няма да работи по подразбиране. - person Ben Voigt; 16.09.2011
comment
@Mooing: Моля, обърнете внимание, че обаждането от T.EXE до A.EXE винаги е индиректно и може да се коригира, за да насочва къде A.EXE действително е заредено. Това са препратките вътре в A.EXE към данни и други функции вътре в него, които не са независими от позицията и не са свързани с библиотеката за импортиране, която свързващият елемент вижда, докато произвежда T.EXE. Предполагам, че линкерът може да излезе и да провери A.EXE, но може да използвате различна версия по време на изпълнение от тази, която съществуваше на компютъра, където link се изпълняваше. - person Ben Voigt; 16.09.2011
comment
@Mooing: Прочетете също тази нишка на microsoft.public.win32.programmer.kernel - person Ben Voigt; 16.09.2011
comment
This field seems relevant only for OBJ files. Това е вдъхващо страхопочитание точно тук. Смятаме, че така работят нашите неща, но не сме сигурни. - person Mooing Duck; 16.09.2011
comment
@Mooing: Авторът вероятно е поканен гост, а не MS инженерът, който е написал зареждащото средство. - person Ben Voigt; 16.09.2011
comment
LoadLibrary е за динамично свързване. Статичното е за предпочитане, но предполагам, че мога да опитам с динамично свързване и да видя докъде ще стигна. - person Mooing Duck; 16.09.2011
comment
@Mooing: LoadLibrary срещу таблица за импортиране няма значение, и двете извикват един и същ код за зареждане. - person Ben Voigt; 16.09.2011