Зачем использовать __declspec (dllexport)? Кажется, работает без него - PullRequest
3 голосов
/ 29 октября 2009

Прошло некоторое время с тех пор, как я программировал на C ++, поэтому идея экспорта / импорта сошла с ума.

Не могли бы вы объяснить, почему использовать __declspec (dllexport) и импортировать что-то, если похоже, что я могу использовать классы из других библиотек без них.

Я создал решение в VC ++ 2005, добавил проект консольного приложения и два проекта библиотек dll. Затем создайте ClassA в проекте LibA, ClassB в проекте LibB.

Как только я включил ClassA.h & ClassB.h в исходный код моего консольного приложения и связал его с LibA.lib и LibB.lib, я смог создавать и использовать экземпляры ClassA и ClassB в консольном приложении. , Поэтому я смог использовать классы, не экспортируя и не импортируя их с помощью __declspec.

Можете ли вы объяснить мне - что мне здесь не хватает.

Ответы [ 3 ]

5 голосов
/ 29 октября 2009

Как только я включил ClassA.h & ClassB.h в исходный код моего консольного приложения и связал его с LibA.lib и LibB.lib, я смог создать и использовать экземпляры ClassA и ClassB в консольном приложении. .

Похоже, вы использовали статическое связывание. Это работает без __declspec(dllexport) так же, как прямое связывание с объектными файлами ваших классов.

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

Возможно, вы не уверены, что пришли из мира Linux, где ситуация иная: все символы по умолчанию видны снаружи.

0 голосов
/ 29 октября 2009

Если вы включаете файлы .h и ссылки на файлы .lib, вы можете удалить декларации DLL. Зачем вам библиотека динамических ссылок, если вам нужны только статические ссылки?

Декларация экспорта помечает функцию как доступную для экспорта. Объявление, которое вы используете, может быть макросом для "extern" и "pascal". Прошло много лет с тех пор, как я это сделал, но я думаю, что вызовы функций DLL имеют другой порядок размещения параметров в стеке, и распределение возвращаемого результата сделано по-другому (паскальский флаг). Объявление extern помогает компоновщику сделать функцию доступной при подключении библиотеки.

Возможно, вы пропустили этап связывания DLL - компоновщик возьмет classA.lib и превратит его в classA.dll (вам может потребоваться настроить файл setupA.def для определения библиотеки DLL). То же относится и к ClassB

0 голосов
/ 29 октября 2009

Вы бы использовали __declspec (dllexport), если хотите предоставить символы в вашей dll для доступа других dll / exe.

Вы бы использовали __declspec (dllimport), если хотите получить доступ к символам в вашей dll / exe, предоставленной другой dll.

Не обязательно, если вы ссылаетесь на статический .lib.

...