Проблемы с компоновщиком C ++, есть ли обобщенный способ их устранения? - PullRequest
2 голосов
/ 27 декабря 2011

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

Есть ли какой-нибудь обобщенный способ найти проблему и исправить ее?

Я использую Visual Studio 2010 и статически связываю свои библиотеки с моей программой. Кажется, мои проблемы всегда связаны с конфликтами с LIBCMT (D) .lib, MSVCRT (D) .lib и несколькими другими библиотеками, которые дважды определяют определенные функции. Если это вообще имеет значение, я намерен избегать использования «управляемого» C ++.

Ответы [ 2 ]

2 голосов
/ 27 декабря 2011

Если ваша ошибка связана с LIBCMT (D) .lib и т.п., обычно это зависит от того, что вы ссылаетесь на библиотеку, которая использует версию CRT, отличную от вашей.Единственное реальное исправление состоит в том, чтобы либо использовать библиотеку, скомпилированную для той же версии CRT, которую вы используете (по этой же причине часто есть версии «debug» и «release»), либо (если вы отчаянно) изменить версию CRTвы используете, чтобы соответствовать одному из библиотеки.

То, что происходит за кулисами, заключается в том, что и вашей программе, и вашей библиотеке нужны функции CRT для правильной работы, и каждая из них уже ссылается на нее.Если они ссылаются на одну и ту же версию, ничего плохого не происходит (компоновщик видит, что он одинаковый и не жалуется), в противном случае существует несколько конфликтующих реализаций одних и тех же функций, поэтому компоновщик не знает, какие из них подходят длякакие объектные модули (а также, поскольку они, вероятно, не являются двоично-совместимыми, внутренние структуры данных двух ЭЛТ будут несовместимы).

1 голос
/ 27 декабря 2011

Конкретные ошибки ссылок, о которых вы упоминали (с библиотеками LIBCMT (D) .lib, MSVCRT (D) .lib), связаны с конфликтами в параметрах генерации кода между модулями / библиотеками в вашей программе.

Когда вы компилируете модуль, компилятор автоматически вставляет в результирующий .obj некоторые ссылки на библиотеки времени выполнения (LIBCMT & MSVCRT). Теперь есть одна версия этих библиотек для каждого режима генерации кода (я имею в виду параметр в Свойствах конфигурации -> C / C ++ -> Генерация кода -> Библиотека времени выполнения). Таким образом, если у вас есть два модуля, скомпилированных с разным режимом, каждый из них будет ссылаться на свою версию библиотеки, компоновщик попытается включить оба, и, конечно, будут дублированные символы, поскольку по существу все символы одинаковы в этих библиотеках отличаются только их реализации.

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

Последний самый сложный. Иногда библиотеки поставляются предварительно скомпилированными, и не всегда поставщик предоставляет информацию об используемом режиме. Хуже того, если вы используете более одной сторонней библиотеки, они могут иметь конфликтующие режимы. В этих случаях у вас нет лучшего варианта, чем метод проб и ошибок.

Также обратите внимание, что каждая версия Visual Studio имеет собственный набор библиотек времени выполнения, поэтому при использовании сторонних библиотек вы должны использовать библиотеки, скомпилированные с той же версией Visual Studio, которую вы используете. Если поставщик не предлагает его, ваш единственный выбор - перекомпилировать себя.

...