Невозможно разрешить символ при использовании lib ... есть идеи? - PullRequest
0 голосов
/ 02 мая 2011

Написано на C (в проект C ++):

У меня есть два проекта в VS08 под одним решением.Один из них представляет собой файл DLL, а другой («runner») представляет собой консольное приложение для использования / тестирования файла DLL.Заголовочный файл содержит заголовочный файл со всеми функциями (__declspec (dllexport)).Когда я использую функции без каких-либо аргументов консольным приложением бегуна, они запускаются ОК.Когда я пытаюсь вызвать функцию с аргументами, я не могу разрешить символ ... ошибка.Странно то, что VS08 распознает функцию, и я могу открыть ее из mainner (runner) с помощью меню, вызываемого правой кнопкой мыши, но не могу найти его.и не импортировать DLL с указателями на функции ... Мне кажется, что функции переименовываются в процессе компиляции, и компоновщик не может найти функции с аргументами.Если бы я мог видеть список новых имен (внутри объектного файла?), Возможно, я мог бы включить их в заголовочный файл, чтобы это исправить?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 02 мая 2011

Написано на C (в проект C ++):

Возможно, это довольно неплохое преимущество.Программа AC не может использовать функции, которые были написаны на C ++.Когда вы используете __declspec (dllexport), функция экспортируется с именем C ++.Который оформлен компилятором, хитрость, позволяющая перегруженным функциям правильно связываться.Компилятор AC не применяет такого же оформления, компоновщик будет жаловаться, что не может найти функцию.

Чтобы это работало, вы должны объявить функцию с помощью декларатора extern "C".Сделайте так, чтобы файл .h выглядел следующим образом:

#ifdef __cplusplus
  extern "C" {
#endif

#undef DLLEXPORT
#ifdef BUILDING_MYDLL
#  define DLLEXPORT __declspec(dllexport)
#else
#  define DLLEXPORT __declspec(dllimport)
#endif

DLLEXPORT void Foo(int arg);
// etc..

#ifdef __cplusplus
  }
#endif

В вашем проекте DLL используйте Project + Properties, C / C ++, Препроцессор и добавьте BUILDING_MYDLL в настройки определений препроцессора.

Краткоеобъяснение этого макро безумия: #ifdef __cplusplus гарантирует, что все объявления DLL объявляются extern "C", когда они компилируются компилятором C ++, чтобы они соответствовали символам компилятора C.Макрос DLLEXPORT гарантирует, что функции экспортируются при сборке DLL, импортируются при связывании библиотеки импорта DLL в другом проекте.

Дополнительную диагностику можно получить с помощью утилиты dumpbin.exe, запустив ее с /опция экспорта в вашей DLL.Он показывает точные имена экспортируемых функций.Запустите его из командной строки Visual Studio.Несоответствие между именами, которые вы видите в выходных стихах сообщений об ошибках компоновщика, является верным признаком проблемы.

0 голосов
/ 02 мая 2011

Во-первых: поиск Intellisense ('open for the rightclick menu' eeeeck?) Не является доказательством;это доказывает, что вы поместили объявление в заголовочный файл;

Вы, вероятно, правы насчет искажения имен: если у вас есть внешние C, вам нужно объявить их внутри extern "C" {} блока:

extern "C" {

    void dostuff(int param1, char* param2);

}

вместо

extern void dostuff(int param1, char* param2);

Наиболее гибкий подход, вероятно, заключается в том, чтобы условно включить внешний "C" вокруг всего заголовочного файла C:

// Sample.h
#if defined(__cplusplus)
extern "C"
{
#endif

// Function declarations

#if defined(__cplusplus)
}
#endif 

См. MSDN для получения дополнительной информации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...