Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/40: Рейтинг темы: голосов - 40, средняя оценка - 4.63
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43

Подключение динамической библиотеки (DLL), MSVC __declspec dllimport dllexport

09.10.2016, 15:36. Показов 8554. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Для экспортирования методов из DLL в заголовочном файле используется конструкция __declspec(dllimport) или __declspec(dllexport)

Часто вижу конструкцию вида:
C++
1
2
3
4
5
#ifdef DLL_EXPORT
    #define DLL_PREFIX __declspec(dllexport)
#else
    #define DLL_PREFIX __declspec(dllimport)
#endif // DLL_EXPORT
И уже перед объявлением методов пишется DLL_PREFIX

Попробовал сделать свою собственную тестовую dll-ку:

DynamicLibrary.proj
в настройках проекта:
C++
1
General->ConfigurationType: Dynamic Library (.dll)
LibraryClass.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef LIBRARY_CLASS_H
#define LIBRARY_CLASS_H
 
#ifdef DLL_EXPORT
    #define DLL_PREFIX __declspec(dllexport)
#else
    #define DLL_PREFIX __declspec(dllimport)
#endif // DLL_EXPORT
 
class LibraryClass
{
public:
    DLL_PREFIX void Open();
    DLL_PREFIX void Close();
};
 
#endif // LIBRARY_CLASS_H
LibraryClass.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include "LibraryClass.h"
#include <iostream>
 
void LibraryClass::Open()
{
    std::cout << "LibraryClass is Opened" << std::endl;
}
 
void LibraryClass::Close()
{
    std::cout << "LibraryClass is Closed" << std::endl;
}
Linking.proj
в настройках проекта эту библиотеку подключаю так
C++
1
2
3
4
5
Файлы библиотеки *.lib и *.dll помещаются в $(OutDir) поэтому добавил путь:
Linker->General->Additional Library Directories: $(OutDir)
 
И подключил саму библиотеку:
Linker->Input->Additional Dependencies: DynamicLibrary.lib
main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include "DynamicLibrary/LibraryClass.h"
 
int main()
{
    LibraryClass obj;
    obj.Open();
    obj.Close();
 
    std::cout << "pause" << std::endl;
    std::getchar();
    return 0;
}
Использую MS Visual Studio 2010. Компилируется и работает.
Вопрос, в каких случаях нужно определять диррективу DLL_EXPORT, и кто ее должен определять?
Тот кто линкуется c DLL? хотя я ее нигде не определил и работает
(может слишком простой проект? как его усложнить, чтобы почувстовать разницу?)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
09.10.2016, 15:36
Ответы с готовыми решениями:

Подключение динамической библиотеки
Всем доброго времени суток. Передо-мной стоит задача подключения собственно написанной библиотеки. И дело в том что я понятие не имею как...

Создание динамической библиотеки (dll) в Dev C++
Кто умеет создавать dll библиотеки в Dev C++, вопрос к вам. Дело в том что я умею создавать header файлы, то бишь заголовочные, но в виду...

Вызов функции одной динамической библиотеки из другой динамической библиотеки
Добрый день! Помогите пожалуйста разобраться со следующим вопросом. Возможно ли из одной библиотеки передать параметры для...

18
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.10.2016, 15:43
DLL_EXPORT нужна что бы переключать dllexport/dllimport в зависимости куда был включен заголовочный файл библиотеки в программу или cpp. dll-ки. Он(дефайн) может по разному называться, и определятся автоматически в шаблонах проекта.

Программы собираемые другими компиляторами не смогу использовать классы из вашей либы, учтите это.
1
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 15:43  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Программы собираемые другими компиляторами не смогу использовать классы из вашей либы, учтите это.
А что может требоваться в других компиляторах? Можно примеры/ссылки?
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.10.2016, 15:45
Цитата Сообщение от Ekventor Посмотреть сообщение
А что может требоваться в других компиляторах? Можно примеры/ссылки?
Ничего просто не будут работать экспорт классов- он не переносим.
Если хочется чтобы ф-ционал был портируемый, следует экспортировать только ф-ции в стиле "С".
0
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 15:46  [ТС]
Это с добавлением extern "C" перед ними?
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.10.2016, 15:48
Цитата Сообщение от Ekventor Посмотреть сообщение
Это с добавлением extern "C" перед ними?
Да и объявление ф-ций не должно содержать сложных типов например std::string (внутри реализации же можно использовать что угодно)
1
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 15:49  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
DLL_EXPORT нужна что бы переключать dllexport/dllimport в зависимости куда был включен заголовочный файл библиотеки в программу или cpp. dll-ки. Он(дефайн) может по разному называться, и определятся автоматически в шаблонах проекта.
Дефайн этот я нигде не определял самостоятельно, ни в проекте dll-ки, ни в проекте exe-шника. Все еще не понял кто ее определил. Студия за меня его определила?
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.10.2016, 15:50
Цитата Сообщение от Avazart Посмотреть сообщение
Он(дефайн) может по разному называться, и определятся автоматически в шаблонах проекта.
Где том в настройках студии можно посмотреть предопределенные макросы/дефайны.
0
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 16:19  [ТС]
Попробовал включить вывод препроцессинга в файл, чтоб посмотреть, что получиться:
С/C++->Preprocessor->Process to a file: Yes(/P)

LibraryClass.i
C++
1
2
3
4
5
6
class LibraryClass
{
public:
    __declspec(dllimport) void Open();
    __declspec(dllimport) void Close();
};
...
C++
1
2
3
4
5
6
7
8
9
void LibraryClass::Open()
{
    std::cout << "LibraryClass is Opened" << std::endl;
}
 
void LibraryClass::Close()
{
    std::cout << "LibraryClass is Closed" << std::endl;
}
main.i
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
 
class LibraryClass
{
public:
    __declspec(dllimport) void Open();
    __declspec(dllimport) void Close();
};
 
int main()
{
    LibraryClass obj;
    obj.Open();
    obj.Close();
 
    std::cout << "pause" << std::endl;
    std::getchar();
    return 0;
}
и там и там __declspec(dllimport), как я и ожидал (т.к. дефайн нигде не определял самостоятельно)
Вложения
Тип файла: zip preprocessed.zip (162.9 Кб, 9 просмотров)
0
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 16:22  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Где том в настройках студии можно посмотреть предопределенные макросы/дефайны.
Еще сейчас заметил в настройках проекта DLL, что там есть такой дефайн: _WINDLL.
Может вы про него говорите?
Миниатюры
Подключение динамической библиотеки (DLL), MSVC __declspec dllimport dllexport   Подключение динамической библиотеки (DLL), MSVC __declspec dllimport dllexport  
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.10.2016, 16:31
Цитата Сообщение от Ekventor Посмотреть сообщение
Использую MS Visual Studio 2010. Компилируется и работает.
Значит утверждение ошибочно.

Добавлено через 1 минуту
Цитата Сообщение от Ekventor Посмотреть сообщение
Еще сейчас заметил в настройках проекта DLL, что там есть такой дефайн: _WINDLL.
Может вы про него говорите?
Возможно, я не знаю как MSVC он называется, в С++Builder это __DLL__

Добавлено через 5 минут
Попробуйте заменить DLL_EXPORT на _WINDLL и проверить еще раз.
0
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 16:37  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Попробуйте заменить DLL_EXPORT на _WINDLL и проверить еще раз.
Оно и так работает с DLL_EXPORT.
Миниатюры
Подключение динамической библиотеки (DLL), MSVC __declspec dllimport dllexport  
0
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 16:39  [ТС]
Заменил
C++
1
#ifdef DLL_EXPORT
на
C++
1
#ifdef _WINDLL
После очистки(Clean) и пересборки(Rebuild) решения появляется ошибка линкера
C++
1
Error   1   error LNK1104: cannot open file 'DynamicLibrary.lib'
и это странно, сам файл создается,
после обычного запуска (не Rebuild), основной проект собирается и все запускается
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.10.2016, 16:43
Цитата Сообщение от Ekventor Посмотреть сообщение
Оно и так работает с DLL_EXPORT.
Заблуждение.

Добавлено через 1 минуту
Цитата Сообщение от Ekventor Посмотреть сообщение
После очистки и пересборки решения появляется ошибка линкера
Естественно, еще одно подтверждение.
0
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 16:45  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
После очистки и пересборки решения появляется ошибка линкера
Естественно, еще одно подтверждение.
с _WINDLL ошибка

Есть возможность проверить? могу скинуть проект
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.10.2016, 16:45
C++
1
#pragma comment(lib,"DynamicLibrary.lib")
Добавлено через 19 секунд
Цитата Сообщение от Ekventor Посмотреть сообщение
с _WINDLL ошибка
Ошибка в кривых руках.

Возьмите скачайте программу PE Explorer и откройте ею DLL и посмотрите таблицу экспорта- она скорее всего будет пустой.
0
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 16:50  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
#pragma comment(lib,"DynamicLibrary.lib")
подключено в настройках, в секции Linker->Input->Additional Dependencies

Цитата Сообщение от Avazart Посмотреть сообщение
Ошибка в кривых руках.
Что не так?

Добавлено через 1 минуту
Цитата Сообщение от Avazart Посмотреть сообщение
Возьмите скачайте программу PE Explorer и откройте ею DLL и посмотрите таблицу экспорта- она скорее всего будет пустой.
Хорошо, попробую
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
09.10.2016, 16:57
Цитата Сообщение от Avazart Посмотреть сообщение
Да и объявление ф-ций не должно содержать сложных типов например std::string (внутри реализации же можно использовать что угодно)
Добавлю на всякий случай: для переносимости между компиляторами объявления
также должны использовать совместимые выравнивания и размеры типов.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.10.2016, 17:09
Цитата Сообщение от Убежденный Посмотреть сообщение
Добавлю на всякий случай: для переносимости между компиляторами объявления
также должны использовать совместимые выравнивания и размеры типов.
Это если использовать структуры/указатели на структуры.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.10.2016, 17:09
Помогаю со студенческими работами здесь

Подключение dll библиотеки
Привет. Для работы с шаговым двигателем мне необходимо воспользоваться приложенной к нему dll библиотекой в которой как раз и реализованы...

Подключение dll библиотеки
Создал консольное приложение, там файл .h и cpp забил нужные функции и скомпилил получив в папке debug name.dll. Как теперь это подключить...

Подключение Dll библиотеки, вылетает программа
Добрый вечер!Помогите пожалуйста разобраться в чем проблема.. Задача: из библиотеки winmm.dll вызвать фукцию PlaySound()(это работает),...

Подключение сторонней библиотеки - как указать путь к .dll файлам
Не могу разобраться как указать путь к .dll файлам пробовал следующее: прописывать в свойствах проекта во вкладке &quot;каталоги...

Подключение библиотеки DLL на C++ через DllImport
Здравствуйте! Подключаю библиотеку к проету, называю функцию const string _dllLocation = @&quot;library.dll&quot;; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru