MSVC неразрешенные внешние символы, связывающие исполняемые файлы - PullRequest
1 голос
/ 12 августа 2011

У меня есть два существующих исполняемых файла A и T в одном и том же решении, оба отлично работали до того, как я коснулся их.В исполняемом файле A есть заголовок, определяющий класс P, и прототип для статического экземпляра MyP.Определения скомпилированы в проекте A. В исполняемом файле T я хотел вызвать функции-члены MyP в проекте A, поэтому я добавил макросы dllimport / export в объявления класса и MyP в заголовках (не в определениях), ивключили заголовки в проект T. Макросы dllimport / export являются стандартными, а A_EXPORTS определен в проекте A, но не в T.

#ifdef A_EXPORTS
#define A_API __declspec(dllexport)
#else
#define A_API __declspec(dllimport)
#endif

//various definitions and includes, defining ENUM_RECORDING_TYPE and ERROR
A_API HFILE viosopen(const _TCHAR *path, ENUM_RECORDING_TYPE rt, int flags);
A_API struct P { 
    ERROR B(SHORT phraseNum);
};
A_API extern P MyP;

Я добавил проект A в качестве зависимости от проекта T в решении,Все равно компилируется нормально, но T предлагает unresolved external symbol "__declspec(import) <snip> referenced in function <snip> для вызовов функций и unresolved external symbol "__declspec(dllimport) class P MyP" <snip> для статического объекта.Я также вижу в выходном журнале, сразу после того, как он начинает связывать: Creating library Debug/A.lib and object Debug/A.exp, что кажется зловещим, поскольку предполагается, что он связывается с существующим исполняемым файлом.

Мой вопрос: как я могу сказать MSVC 2010, где они?Я подумал, что просто установив A в качестве зависимости, он автоматически это выяснит.Я могу ссылаться на существующий исполняемый файл, верно?

Ответы [ 2 ]

2 голосов
/ 13 августа 2011

К статически для связывания вашей программы вам не нужен материал __declspec (), и вам не нужен отдельный проект для создания файла LIB.Я думаю, что вы можете просто создать ссылку, используя файл .obj из вашего проекта A.

Ваш проект A имеет файл заголовка и, предположительно, файл .cpp, который содержит реализацию элементов, описанных в этом заголовке.Допустим, ваш заголовочный файл foo.h и связанная с ним реализация foo.cpp.После компиляции в промежуточной папке <solutiondir>\A\Debug или <solutiondir>\A\release должен быть промежуточный файл foo.obj.Этот файл может использоваться компоновщиком.

В свойствах проекта T найдите Linker |Введите и измените свойство «Дополнительные зависимости», включив в него файл foo.obj.Один из подходов заключается в использовании относительного пути к файлу для поиска файла - например, ..\A\Debug\foo.obj в вашей конфигурации отладки.Другой подход заключается в использовании простого имени файла в «Дополнительные зависимости» - foo.obj - и затем использовать Linker |Генерал |Дополнительные каталоги библиотек ", чтобы помочь компоновщику найти файл - например, ..\A\$(IntDir). Использование макроса $(IntDir) имеет то преимущество, что то же значение работает для параметров отладки и выпуска.

Не забудьте настроить сборкузависимость от вашего T-проекта до вашего A-проекта, чтобы убедиться, что сначала проект A скомпилирован. В противном случае файл foo.obj может не существовать, когда его ищет компоновщик T. В свойствах Solution выберите Project Dependencies, а затем установите ProjectT зависит от проекта A.

На динамически ссылка, вам нужно использовать файл A.LIB, как сказал @ajay. __declspec(DllImport) сообщает компилятору, какие функции и данные вы импортируете, ноне сообщает, откуда вы импортируете эти вещи.

Использование файла A.LIB в качестве входных данных для компоновщика во многом аналогично использованию файла foo.obj в случае статической компоновки, за исключением того, что libфайл попадает в выходной каталог решения <solutiondir>\Debug вместо промежуточного каталога проекта <solutiondir>\A\Debug.

This wАлгоритм при создании и использовании DLL может быть полезным фоном.

0 голосов
/ 12 августа 2011

Я предполагаю, что проект A - это DLL, а не EXE, который успешно создает LIB-файл. Вам необходимо использовать A.LIB в качестве входных данных компоновщика в проекте B. Простое создание файла LIB не приводит к тому, что другие проекты автоматически ссылаются на него.

...