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

В качестве расширения вопроса неразрешенный внешний символ 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 не заметил, что это будет проблемой? Плохой Майкрософт. - 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