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

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

7 голосов
/ 08 августа 2008

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

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

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

Код, который указан как имеющий проблему в IOCompletionPort.obj, на самом деле не использует std::string напрямую, но вызывает класс, который: Comms::Exception принимает std::string и значение GetLastError или WSAGetLastError.

Функция, упомянутая в ошибке (GetMessage), реализована, но является виртуальной функцией, поэтому другие классы могут переопределять ее при необходимости. Однако, похоже, что компилятор сделал это как версию Ansi, но я не могу найти какие-либо параметры в настройках, которые бы контролировали это. Я подозреваю, что это может быть проблемой, но так как вариантов для библиотеки очень мало, я точно не знаю. Однако оба проекта указывают _MBCS в опциях компилятора.

-------------------- Конфигурация: TestComms - Win32 Debug -------------------- Связывание ... Comms.lib (IOCompletionPort.obj) : ошибка LNK2001: неразрешенный внешний символ "public: virtual class станд :: basic_string, класс std :: allocator> __thiscall Comms :: Exception :: GetMessageA (void) const "(? GetMessageA @ Исключение @ Коммуникационный @@ ВБО? AV? $ Basic_string @ DU? $ Char_traits @ D @ станд @@ V? $ Распределитель @ D @ 2 @@ станд @@ XZ) Отладка / TestComms.exe: фатальная ошибка LNK1120: 1 неразрешенная внешность Ошибка выполнения link.exe.

TestComms.exe - 2 ошибки, 0 предупреждений

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

Ответы [ 5 ]

4 голосов
/ 08 августа 2008

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

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

1 голос
/ 09 августа 2008

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

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

0 голосов
/ 16 сентября 2008

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

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

0 голосов
/ 08 августа 2008

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

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

0 голосов
/ 08 августа 2008

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

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