Проблемы со связью (VC6)

Я открыл старую рабочую область, которая представляет собой библиотеку и ее тестовый набор. Раньше он работал нормально, но теперь нет, и более старые версии кода не работают с теми же ошибками. Я пробовал воссоздать проект, и это тоже вызывает те же ошибки. В настройках проекта все выглядит не так, как надо, а созданный код работает в основном приложении.

Я удалил большинство файлов и сократил их до минимума, чтобы сгенерировать ошибку. К сожалению, я не могу опубликовать проект, так как он используется в производственном коде.

Ошибка компоновщика 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)

Какие-либо предложения? Я потерял из-за этого большую часть утра и тоже не хочу терять большую часть дня.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
11
0
1 166
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Одна из возможностей заключается в «изменении имен» Win32 ANSI / Unicode, которое превращает символ GetMessage в GetMessageA или GetMessageW. Есть три возможности:

  1. Windows.h не загружен, поэтому GetMessage остается GetMessage

  2. Windows.h был загружен с символами, установленными для ANSI, поэтому GetMessage становится GetMessageA

  3. 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 :-(

  1. Это подтверждено. Ничего лишнего.
  2. Я сделал это - удалил каталоги сборки
  3. Я никогда не использую жестко запрограммированные пути.

Предполагая, что вы не возились с настройками проекта, удаляя то, чего у вас не должно быть (именно здесь, я бы ожидал, будут внешние зависимости, такие как 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 грубо работают со всеми другими пространствами имен.

Другие вопросы по теме