Я открыл старое рабочее пространство, которое представляет собой библиотеку и ее тестовый комплект. Раньше он работал нормально, но сейчас нет, и старые версии кода не работают с одинаковыми ошибками. Я попытался воссоздать проект, и это также вызывает те же ошибки. Ничто не выглядит не в порядке в настройках проекта, и сгенерированный код работает в основном приложении.
Я удалил большинство файлов и довел их до минимума, чтобы сгенерировать ошибку. К сожалению, я не могу опубликовать проект, так как он используется в рабочем коде.
Ошибка компоновщика LNK2001, которую я получаю, обычно означает, что я оставил библиотеку или забыл реализовать виртуальную функцию. Однако это часть стандартной библиотеки шаблонов - и это заголовок.
Код, который указан как имеющий проблему в IOCompletionPort.obj, на самом деле не использует std::string
напрямую, но вызывает класс, который делает: Comms::Exception
принимает a std::string
и значение GetLastError
or WSAGetLastError
.
Функция, упомянутая в error ( GetMessage
), реализована, но является виртуальной функцией, поэтому другие классы могут переопределить ее, если это необходимо. Однако кажется, что компилятор сделал это как версию Ansi, но я не могу найти какие-либо параметры в настройках, которые бы контролировали это. Я подозреваю, что это может быть проблемой, но так как вариантов для библиотеки очень мало, я точно не знаю. Однако оба проекта указывают _MBCS в опциях компилятора.
-------------------- Конфигурация: TestComms - Win32 Debug -------------------- Связывание ... Comms.lib (IOCompletionPort.obj): ошибка LNK2001: неразрешенный внешний символ "public: виртуальный класс std :: basic_string, класс std :: allocator> __thiscall Comms :: Exception :: GetMessageA (void) const" (? GetMessageA @ Exception @ Comms @@ UBE? AV? $ Basic_string @ DU? $ Char_traits @ D @ std @@ V? $ Allocator @ D @ 2 @@ std @@ XZ) Отладка / TestComms.exe: фатальная ошибка LNK1120: 1 неразрешенная внешняя ошибка Ошибка выполнения link.exe.
TestComms.exe - 2 ошибки, 0 предупреждений
Какие-либо предложения? Я потерял большую часть утра на это и не хочу терять большую часть дня тоже.
Одна из возможностей заключается с Win32 ANSI / Unicode «имя-коверкая», который превращает символ GetMessage
в любой GetMessageA
или GetMessageW
. Есть три варианта:
Windows.h не был загружен, поэтому
GetMessage
остаетсяGetMessage
Windows.h был загружен с набором символов для ANSI, поэтому
GetMessage
становитсяGetMessageA
Windows.h был загружен с символами, установленными для Unicode, поэтому
GetMessage
становитсяGetMessageW
Если вы скомпилировали два разных файла способами, которые запускают два разных сценария, вы получите ошибку компоновщика. Сообщение об ошибке указывает, что Comms::Exception
класс был экземпляром # 2, выше - возможно, он используется где-то, что windows.h не был загружен?
Другие вещи, которые я бы сделал на вашем месте, просто как обычное дело:
1) Убедитесь, что мои пути включения и библиотеки не содержат ничего, чего я не ожидаю.
2) Выполните «build clean», а затем вручную проверьте его, удалив любые дополнительные объектные файлы, если это необходимо.
3) Убедитесь, что в выражениях include нет жестко заданных путей, которые не означают того, что они имели в виду при первоначальной перестройке проекта.
РЕДАКТИРОВАТЬ: Борьба с форматированием :(
windows.h объявлен в верхней части IOCompletionPort.h как включаемый - мне надоело видеть 7 строк, чтобы включить только один файл, поэтому я обернул его своим собственным файлом и включил его сам. Он также содержит некоторые дополнительные #defines (то есть ULONG_PTR), поскольку наше основное приложение не будет компилироваться с установленным Platform SDK :-(
- Это подтверждается. Нет ничего неуместного.
- Я сделал это - удалил каталоги сборки
- Я никогда не использую жестко закодированные пути.
Предполагая, что вы не сгорели с настройками проекта, удалив что-то, чего у вас не должно быть (вот где я ожидаю внешних зависимостей, таких как User32.lib):
Проверить Инструменты | Варианты | Справочники | Библиотеки (исходя из памяти) и убедитесь, что вы не пропускаете общедоступные директории lib для разных сортов (опять же, без VC6 передо мной, я не могу вам сказать, что они есть)
@ Курт: Я думаю, что вы пришли ближе всего. Я не проверял это, но я думаю, что дал своего рода ответ на свой первоначальный вопрос.
GetMessage - это определение в Windows.h, заключенное в блок ifndef для переключения между Ansi (GetMessageA) и Unicode (GetMessageW).
Это общая проблема, связанная с тем, как Microsoft обрабатывает API-интерфейсы ANSI и Unicode. Поскольку все они (или почти все) выполняются путем определения макросов для имен функций, которые соответствуют версиям имен функций «A» или «W», вы не можете безопасно иметь идентификатор в своем пространстве имен / class / struct / enum / функция, которая соответствует имени Windows API.
Макросы windows.h запускаются неактивно во всех других пространствах имен.