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

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

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

Ошибка компоновщика LNK2001, которую я получаю, обычно означает, что я оставил библиотеку или забыл реализовать виртуальную функцию. Однако это часть стандартной библиотеки шаблонов - и это заголовок.

Код, который указан как имеющий проблему в IOCompletionPort.obj, на самом деле не использует std::stringнапрямую, но вызывает класс, который делает: Comms::Exceptionпринимает a std::stringи значение GetLastErroror 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 предупреждений

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

8.08.2008 13:13:08
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) Выполните «build clean», а затем вручную проверьте его, удалив любые дополнительные объектные файлы, если это необходимо.

3) Убедитесь, что в выражениях include нет жестко заданных путей, которые не означают того, что они имели в виду при первоначальной перестройке проекта.

РЕДАКТИРОВАТЬ: Борьба с форматированием :(

6
21.12.2015 15:23:23

windows.h объявлен в верхней части IOCompletionPort.h как включаемый - мне надоело видеть 7 строк, чтобы включить только один файл, поэтому я обернул его своим собственным файлом и включил его сам. Он также содержит некоторые дополнительные #defines (то есть ULONG_PTR), поскольку наше основное приложение не будет компилироваться с установленным Platform SDK :-(

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

Предполагая, что вы не сгорели с настройками проекта, удалив что-то, чего у вас не должно быть (вот где я ожидаю внешних зависимостей, таких как User32.lib):

Проверить Инструменты | Варианты | Справочники | Библиотеки (исходя из памяти) и убедитесь, что вы не пропускаете общедоступные директории lib для разных сортов (опять же, без VC6 передо мной, я не могу вам сказать, что они есть)

0
8.08.2008 13:57:57

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

GetMessage - это определение в Windows.h, заключенное в блок ifndef для переключения между Ansi (GetMessageA) и Unicode (GetMessageW).

1
9.08.2008 10:50:00

Это общая проблема, связанная с тем, как Microsoft обрабатывает API-интерфейсы ANSI и Unicode. Поскольку все они (или почти все) выполняются путем определения макросов для имен функций, которые соответствуют версиям имен функций «A» или «W», вы не можете безопасно иметь идентификатор в своем пространстве имен / class / struct / enum / функция, которая соответствует имени Windows API.

Макросы windows.h запускаются неактивно во всех других пространствах имен.

0
16.09.2008 18:52:32