Вопрос

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

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

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

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

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

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

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

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

Это было полезно?

Решение

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

2) Выполните "чистую сборку", а затем вручную проверьте ее, удалив при необходимости все дополнительные объектные файлы.

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

Редактировать:Борьба с форматированием :(

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

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

Получить сообщение является определением в Windows.h, заключенным в блок ifndef для переключения между Ansi (GetMessageA) и Unicode (GetMessageW).

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

Проверьте Tools | Options | Directories | Libraries (здесь выбирается из памяти) и убедитесь, что вы не пропускаете общие каталоги библиотек для всего сада (опять же, без VC6 передо мной, я не могу сказать вам, что это такое)

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

Макросы windows.h работают грубо по отношению ко всем остальным пространствам имен.

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

  1. Это подтверждается.Здесь нет ничего неуместного.
  2. Я сделал это - удалил каталоги сборки
  3. Я никогда не использую жестко запрограммированные пути.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top