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

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

09.10.2016, 15:36. Просмотров 4326. Ответов 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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.10.2016, 15:36
Ответы с готовыми решениями:

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

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

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

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

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

Программы собираемые другими компиляторами не смогу использовать классы из вашей либы, учтите это.
1
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 15:43  [ТС] 3
Цитата Сообщение от Avazart Посмотреть сообщение
Программы собираемые другими компиляторами не смогу использовать классы из вашей либы, учтите это.
А что может требоваться в других компиляторах? Можно примеры/ссылки?
0
Эксперт С++
8353 / 6100 / 610
Регистрация: 10.12.2010
Сообщений: 28,356
Записей в блоге: 29
09.10.2016, 15:45 4
Цитата Сообщение от Ekventor Посмотреть сообщение
А что может требоваться в других компиляторах? Можно примеры/ссылки?
Ничего просто не будут работать экспорт классов- он не переносим.
Если хочется чтобы ф-ционал был портируемый, следует экспортировать только ф-ции в стиле "С".
0
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 15:46  [ТС] 5
Это с добавлением extern "C" перед ними?
0
Эксперт С++
8353 / 6100 / 610
Регистрация: 10.12.2010
Сообщений: 28,356
Записей в блоге: 29
09.10.2016, 15:48 6
Цитата Сообщение от Ekventor Посмотреть сообщение
Это с добавлением extern "C" перед ними?
Да и объявление ф-ций не должно содержать сложных типов например std::string (внутри реализации же можно использовать что угодно)
1
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 15:49  [ТС] 7
Цитата Сообщение от Avazart Посмотреть сообщение
DLL_EXPORT нужна что бы переключать dllexport/dllimport в зависимости куда был включен заголовочный файл библиотеки в программу или cpp. dll-ки. Он(дефайн) может по разному называться, и определятся автоматически в шаблонах проекта.
Дефайн этот я нигде не определял самостоятельно, ни в проекте dll-ки, ни в проекте exe-шника. Все еще не понял кто ее определил. Студия за меня его определила?
0
Эксперт С++
8353 / 6100 / 610
Регистрация: 10.12.2010
Сообщений: 28,356
Записей в блоге: 29
09.10.2016, 15:50 8
Цитата Сообщение от Avazart Посмотреть сообщение
Он(дефайн) может по разному называться, и определятся автоматически в шаблонах проекта.
Где том в настройках студии можно посмотреть предопределенные макросы/дефайны.
0
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 16:19  [ТС] 9
Попробовал включить вывод препроцессинга в файл, чтоб посмотреть, что получиться:
С/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), как я и ожидал (т.к. дефайн нигде не определял самостоятельно)
0
Вложения
Тип файла: zip preprocessed.zip (162.9 Кб, 3 просмотров)
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 16:22  [ТС] 10
Цитата Сообщение от Avazart Посмотреть сообщение
Где том в настройках студии можно посмотреть предопределенные макросы/дефайны.
Еще сейчас заметил в настройках проекта DLL, что там есть такой дефайн: _WINDLL.
Может вы про него говорите?
0
Миниатюры
Подключение динамической библиотеки (DLL), MSVC __declspec dllimport dllexport   Подключение динамической библиотеки (DLL), MSVC __declspec dllimport dllexport  
Эксперт С++
8353 / 6100 / 610
Регистрация: 10.12.2010
Сообщений: 28,356
Записей в блоге: 29
09.10.2016, 16:31 11
Цитата Сообщение от 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  [ТС] 12
Цитата Сообщение от Avazart Посмотреть сообщение
Попробуйте заменить DLL_EXPORT на _WINDLL и проверить еще раз.
Оно и так работает с DLL_EXPORT.
0
Миниатюры
Подключение динамической библиотеки (DLL), MSVC __declspec dllimport dllexport  
8 / 8 / 4
Регистрация: 09.06.2013
Сообщений: 43
09.10.2016, 16:39  [ТС] 13
Заменил
C++
1
#ifdef DLL_EXPORT
на
C++
1
#ifdef _WINDLL
После очистки(Clean) и пересборки(Rebuild) решения появляется ошибка линкера
C++
1
Error   1   error LNK1104: cannot open file 'DynamicLibrary.lib'
и это странно, сам файл создается,
после обычного запуска (не Rebuild), основной проект собирается и все запускается
0
Эксперт С++
8353 / 6100 / 610
Регистрация: 10.12.2010
Сообщений: 28,356
Записей в блоге: 29
09.10.2016, 16:43 14
Цитата Сообщение от Ekventor Посмотреть сообщение
Оно и так работает с DLL_EXPORT.
Заблуждение.

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

Есть возможность проверить? могу скинуть проект
0
Эксперт С++
8353 / 6100 / 610
Регистрация: 10.12.2010
Сообщений: 28,356
Записей в блоге: 29
09.10.2016, 16:45 16
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  [ТС] 17
Цитата Сообщение от Avazart Посмотреть сообщение
#pragma comment(lib,"DynamicLibrary.lib")
подключено в настройках, в секции Linker->Input->Additional Dependencies

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

Добавлено через 1 минуту
Цитата Сообщение от Avazart Посмотреть сообщение
Возьмите скачайте программу PE Explorer и откройте ею DLL и посмотрите таблицу экспорта- она скорее всего будет пустой.
Хорошо, попробую
0
Ушел с форума
Эксперт С++
16411 / 7386 / 1184
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
09.10.2016, 16:57 18
Цитата Сообщение от Avazart Посмотреть сообщение
Да и объявление ф-ций не должно содержать сложных типов например std::string (внутри реализации же можно использовать что угодно)
Добавлю на всякий случай: для переносимости между компиляторами объявления
также должны использовать совместимые выравнивания и размеры типов.
0
Эксперт С++
8353 / 6100 / 610
Регистрация: 10.12.2010
Сообщений: 28,356
Записей в блоге: 29
09.10.2016, 17:09 19
Цитата Сообщение от Убежденный Посмотреть сообщение
Добавлю на всякий случай: для переносимости между компиляторами объявления
также должны использовать совместимые выравнивания и размеры типов.
Это если использовать структуры/указатели на структуры.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.10.2016, 17:09

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.