Я открыл старую рабочую область, которая представляет собой библиотеку и ее тестовый набор. Раньше он работал нормально, но теперь нет, и более старые версии кода не работают с теми же ошибками. Я пробовал воссоздать проект, и это тоже вызывает те же ошибки. В настройках проекта все выглядит не так, как надо, а созданный код работает в основном приложении.
Я удалил большинство файлов и сократил их до минимума, чтобы сгенерировать ошибку. К сожалению, я не могу опубликовать проект, так как он используется в производственном коде.
Ошибка компоновщика LNK2001, которую я получаю, обычно означает, что я прекратил работу с библиотекой или забыл реализовать виртуальную функцию. Однако это часть стандартной библиотеки шаблонов - и при этом является заголовком.
Код, который указан как имеющий проблему в IOCompletionPort.obj, на самом деле не использует std::string напрямую, но вызывает класс, который это делает: Comms::Exception принимает std::string и значение GetLastError или WSAGetLastError.
Функция, упомянутая в ошибке (GetMessage), реализована, но является виртуальной функцией, поэтому другие классы могут переопределить ее при необходимости. Однако похоже, что компилятор сделал это как версию Ansi, но я не могу найти никаких параметров в настройках, которые бы это контролировали. Я подозреваю, что это может быть проблемой, но поскольку вариантов для библиотеки очень мало, я не могу знать наверняка. Однако в обоих проектах необходимо указать _MBCS в параметрах компилятора.
--------------------Configuration: TestComms - Win32 Debug-------------------- Linking... Comms.lib(IOCompletionPort.obj) : error LNK2001: unresolved external symbol "public: virtual class std::basic_string,class 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) Debug/TestComms.exe : fatal error LNK1120: 1 unresolved externals Error executing link.exe.
TestComms.exe - 2 error(s), 0 warning(s)
Какие-либо предложения? Я потерял из-за этого большую часть утра и тоже не хочу терять большую часть дня.





Одна из возможностей заключается в «изменении имен» 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) Выполните «чистую сборку», а затем вручную проверьте ее, удалив при необходимости все лишние объектные файлы.
3) Убедитесь, что в операторах include нет жестко запрограммированных путей, которые не означают то, что они имели в виду при первоначальной перестройке проекта.
Обновлено: Борьба с форматированием :(
windows.h объявлен в верхней части IOCompletionPort.h как включаемый - мне надоело видеть 7 строк только для включения 1 файла, поэтому я обернул его в отдельный файл и включил его. Он также содержит некоторые дополнительные #defines (например, ULONG_PTR), поскольку наше основное приложение не будет компилироваться с установленным Platform SDK :-(
Предполагая, что вы не возились с настройками проекта, удаляя то, чего у вас не должно быть (именно здесь, я бы ожидал, будут внешние зависимости, такие как User32.lib):
Проверить Инструменты | Опции | Справочники | Библиотеки (здесь идет по памяти) и убедитесь, что вы не упускаете из виду общие каталоги библиотек для всех садов (опять же, без VC6 передо мной, я не могу сказать вам, что это такое)
@Curt: Думаю, ты подошел ближе всех. Я не тестировал это, но думаю, что дал ответ на свой первоначальный вопрос.
GetMessage - это определение в Windows.h, заключенное в блок ifndef для переключения между Ansi (GetMessageA) и Unicode (GetMessageW).
Это общая проблема, связанная с тем, как Microsoft обрабатывает API-интерфейсы ANSI и Unicode. Поскольку все они (или почти все) выполняются путем определения макросов для имен функций, которые разрешаются в версии имен функций A или W, вы не можете безопасно иметь идентификатор в вашем пространстве имен / class / struct / enum / функция, которая соответствует имени Windows API.
Макросы windows.h грубо работают со всеми другими пространствами имен.