C++ — Подключение сторонней библиотеки к проекту на С++


Содержание

Borland C++ 3.0 — Как подключить LIB файл к проекту?

Добрый день! Мне необходимо использовать стороннюю библиотеку функций. Имеется один LIB и один заголовочный файл. Вроде бы делаю все правильно. Создаю новый проект. Жму Project->Add Item, выбираю UTILITYS.LIB (нужная мне библиотека), жму Add->Done. Затем в main.cpp подключаю заголовочный файл для этой библиотеки (#include «5510drv.h»). В пути поиска добавил каталог с LIB’ом. Вызов какой нибудь функции из этой библиотеки приводит к ошибке — Linker Error: Undefined symbol ХХХХХХХ (функция библиотеки) in module main.cpp. Просматривая форум таких вопросов больше не нашел, у всех все компилируется. Подскажите кто может.

P.S. Думая что дело в путях я положил заголовочый и LIB файл в каталог с исходными файлами. Не помогло. Что еще может быть?

11 ответов

Originally posted by coderinside
Добрый день! Мне необходимо использовать стороннюю библиотеку функций. Имеется один LIB и один заголовочный файл. Вроде бы делаю все правильно. Создаю новый проект. Жму Project->Add Item, выбираю UTILITYS.LIB (нужная мне библиотека), жму Add->Done. Затем в main.cpp подключаю заголовочный файл для этой библиотеки (#include «5510drv.h»). В пути поиска добавил каталог с LIB’ом. Вызов какой нибудь функции из этой библиотеки приводит к ошибке — Linker Error: Undefined symbol ХХХХХХХ (функция библиотеки) in module main.cpp. Просматривая форум таких вопросов больше не нашел, у всех все компилируется. Подскажите кто может.

P.S. Думая что дело в путях я положил заголовочый и LIB файл в каталог с исходными файлами. Не помогло. Что еще может быть?

Попробуй через #pragma comment(lib,libname.lib);

Добрый день! Мне необходимо использовать стороннюю библиотеку функций. Имеется один LIB и один заголовочный файл. Вроде бы делаю все правильно. Создаю новый проект. Жму Project->Add Item, выбираю UTILITYS.LIB (нужная мне библиотека), жму Add->Done. Затем в main.cpp подключаю заголовочный файл для этой библиотеки (#include «5510drv.h»). В пути поиска добавил каталог с LIB’ом. Вызов какой нибудь функции из этой библиотеки приводит к ошибке — Linker Error: Undefined symbol ХХХХХХХ (функция библиотеки) in module main.cpp. Просматривая форум таких вопросов больше не нашел, у всех все компилируется. Подскажите кто может.

P.S. Думая что дело в путях я положил заголовочый и LIB файл в каталог с исходными файлами. Не помогло. Что еще может быть?

Здравствуйте, товаришь по несчастью! У меня аналогичная проблема:)
Вот что мне ответили на другом форуме.
Сначало опустили за фразу (#include «AX10412.lib»).
Вроде lib-ский файл не в самом CPP-ом подключается.
А вот что мне сказал один человек

Подозреваю, что там в хедерах
#ifdef __cplusplus
extern «C» <
#endif
.
#ifdef __cplusplus
>
#endif

пропущены
Сам пока не пробывалможет поможет:)
И вам желаю удачи!

Пошаговое руководство. Создание и использование статической библиотеки (C++) Walkthrough: Creating and Using a Static Library (C++)

В этом пошаговом руководстве описывается создание статической библиотеки (LIB-файла) для использования с приложениями C++. This step-by-step walkthrough shows how to create a static library (.lib file) for use with C++ apps. Статические библиотеки являются хорошим способом повторного использования кода. Using a static library is a great way to reuse code. Вместо того чтобы воссоздание те же подпрограммы в каждом приложении, требуются функциональные возможности, вы пишете одно время в статической библиотеке и затем ссылаться на него из приложений. Rather than reimplementing the same routines in every app that requires the functionality, you write them one time in a static library and then reference it from the apps. Код, подключенный из статической библиотеки, становится частью вашего приложения — для использования кода не нужно устанавливать еще какой-либо файл. Code linked from a static library becomes part of your app—you don’t have to install another file to use the code.

В этом пошаговом руководстве рассматриваются следующие задачи: This walkthrough covers these tasks:

Предварительные требования Prerequisites

Для работы необходимо владеть основами языка C++. An understanding of the fundamentals of the C++ language.

Создание проекта статической библиотеки Creating a static library project

Инструкции по созданию проекта зависит от того, используете ли вы Visual Studio 2020 г. или более ранней версии. The instructions for how to create the project vary depending on whether you are using Visual Studio 2020 or an earlier version. Убедитесь в наличии правильной версии, установите в левом верхнем углу этой страницы. Make sure you have the correct version set in the upper left of this page.

Создание проекта статической библиотеки в Visual Studio 2020 г. To create a static library project in Visual Studio 2020

В строке меню выберите файл > New > проекта открыть создайте новый проект диалоговое окно. On the menu bar, choose File > New > Project to open the Create a New Project dialog box.

В верхней части диалогового окна, задайте языка для C++, задайте платформы для Windowsи задайте типпроекта для библиотеки. At the top of the dialog, set Language to C++, set Platform to Windows, and set Project type to Library.

В отфильтрованном списке типов проектов выберите статическая библиотека выберите Далее. From the filtered list of project types, choose Static Library then choose Next. На следующей странице введите MathFuncsLib в имя поле для указания имени проекта и указать расположение проекта, при необходимости. In the next page, enter MathFuncsLib in the Name box to specify a name for the project, and specify the project location if desired.

Выберите создать кнопку, чтобы создать клиентский проект. Choose the Create button to create the client project.

Создание проекта статической библиотеки в Visual Studio 2020 To create a static library project in Visual Studio 2020

В строке меню выберите Файл > Создать > Проект. On the menu bar, choose File > New > Project.

В левой части новый проект диалоговое окно последовательно раскройте элементы установленные > Visual C++, а затем выберите Windows Desktop. In the left pane of the New Project dialog box, expand Installed > Visual C++, and then select Windows Desktop. В центральной области выберите мастер создания классических приложений Windows. In the center pane, select Windows Desktop Wizard.

Укажите имя для проекта, например MathFuncsLib, в поле Имя . Specify a name for the project—for example, MathFuncsLib—in the Name box. Укажите имя для решения, например StaticLibrary, в поле Имя решения . Specify a name for the solution—for example, StaticLibrary—in the Solution Name box. Нажмите кнопку ОК . Choose the OK button.

В разделе тип приложениявыберите статическая библиотека (.lib). Under Application type, select Static Library (.lib).

В разделе Дополнительные параметры, снимите флажок предкомпилированный заголовок «флажок». Under Additional Options, un-check the Precompiled header check box.

Выберите ОК для создания проекта. Choose OK to create the project.

Создание проекта статической библиотеки в Visual Studio 2015 To create a static library project in Visual Studio 2015

В строке меню выберите Файл > Создать > Проект. On the menu bar, choose File > New > Project.

В новый проект диалогового окна разверните узел установленные > шаблоны > Visual C++ , и затем выберите Win32. In the New Project dialog box, expand Installed > Templates > Visual C++, and then select Win32. В центральной области выберите Консольное приложение Win32. In the center pane, select Win32 Console Application.

Укажите имя для проекта, например MathFuncsLib, в поле Имя . Specify a name for the project—for example, MathFuncsLib—in the Name box. Укажите имя для решения, например StaticLibrary, в поле Имя решения . Specify a name for the solution—for example, StaticLibrary—in the Solution Name box. Нажмите кнопку ОК . Choose the OK button.

Нажмите кнопку Далее. Click Next.

В разделе тип приложениявыберите статическую библиотеку. Under Application type, select Static library. Затем снимите флажок предкомпилированный заголовок можно выбрать Готово. Then uncheck the Precompiled header box and choose Finish.

Добавление класса в статическую библиотеку Adding a class to the static library

Добавление класса в статическую библиотеку To add a class to the static library

Чтобы создать файл заголовка для нового класса, откройте контекстное меню для MathFuncsLib проекта в среде обозревателе решений, а затем выберите добавить > Новый элемент. To create a header file for a new class, open the shortcut menu for the MathFuncsLib project in Solution Explorer, and then choose Add > New Item. В диалоговом окне Добавление нового элемента в левой области в разделе Visual C++ выберите Код. In the Add New Item dialog box, in the left pane, under Visual C++, select Code. В центральной области выберите Заголовочный файл (.h). In the center pane, select Header File (.h). Укажите имя для файла заголовка, например MathFuncsLib.h, и нажмите кнопку Добавить . Specify a name for the header file—for example, MathFuncsLib.h—and then choose the Add button. Отобразится пустой файл заголовка. A blank header file is displayed.


Добавьте класс с именем MyMathFuncs общие арифметические операции, такие как сложение, вычитание, умножение и деление. Add a class named MyMathFuncs to do common mathematical operations such as addition, subtraction, multiplication, and division. Код должен выглядеть как: The code should resemble:

Для создания исходного файла для нового класса, откройте контекстное меню для MathFuncsLib в проекте обозревателе решений, а затем выберите добавить > Новый элемент. To create a source file for the new class, open the shortcut menu for the MathFuncsLib project in Solution Explorer, and then choose Add > New Item. В диалоговом окне Добавление нового элемента в левой области в разделе Visual C++ выберите Код. In the Add New Item dialog box, in the left pane, under Visual C++, select Code. В центральной области выберите Файл C++ (.cpp). In the center pane, select C++ File (.cpp). Укажите имя исходного файла, например MathFuncsLib.cpp, и нажмите кнопку Добавить . Specify a name for the source file—for example, MathFuncsLib.cpp—and then choose the Add button. Отобразится пустой исходный файл. A blank source file is displayed.

Используйте этот исходный файл для реализации функций MyMathFuncs. Use this source file to implement the functionality for MyMathFuncs. Код должен выглядеть как: The code should resemble:

Скомпилируйте статическую библиотеку, выбрав построения > построить решение в строке меню. Compile the static library by selecting Build > Build Solution on the menu bar. Компиляция создает статическую библиотеку, который может использоваться другими программами. Compiling creates a static library that can be used by other programs.

При выполнении сборки из командной строки Visual Studio программа собирается в два этапа. When you build on the Visual Studio command line, you must build the program in two steps. Сначала запустите cl /c /EHsc MathFuncsLib.cpp скомпилировать код и создать файл объекта с именем MathFuncsLib.obj . First, run cl /c /EHsc MathFuncsLib.cpp to compile the code and create an object file that’s named MathFuncsLib.obj . (Команда cl вызывает компилятор Cl.exe, а параметр /c дает указание компилировать без компоновки. (The cl command invokes the compiler, Cl.exe, and the /c option specifies compile without linking. Дополнительные сведения см. в разделе /c (компиляция без связывания).) Во-вторых, запустите lib MathFuncsLib.obj чтобы связать код и создать статическую библиотеку MathFuncsLib.lib . For more information, see /c (Compile Without Linking).) Second, run lib MathFuncsLib.obj to link the code and create the static library MathFuncsLib.lib . (Команда lib вызывает диспетчер библиотек, Lib.exe. (The lib command invokes the Library Manager, Lib.exe. Дополнительные сведения см. в разделе LIB Reference.) For more information, see LIB Reference.)

Создание консольного приложения C++, ссылающегося на статическую библиотеку Creating a C++ console app that references the static library

Чтобы создать C++ консольное приложение, которое ссылается на статической библиотеки в Visual Studio 2020 г. To create a C++ console app that references the static library in Visual Studio 2020

В обозревателе решений, щелкните правой кнопкой мыши на верхний узел для решения и выберите добавить > новый проект открыть Добавление нового проекта диалоговое окно. In Solution Explorer, right-click on the top node for the solution and choose Add > New Project to open the Add a New Project dialog box.

В верхней части диалогового окна, задайте языка для C++, задайте платформы для Windowsи задайте типпроекта для консоли. At the top of the dialog, set Language to C++, set Platform to Windows, and set Project type to Console.

В отфильтрованном списке типов проектов выберите консольное приложение выберите Далее. From the filtered list of project types, choose Console App then choose Next. На следующей странице введите MyExecRefsLib в имя поле для указания имени проекта и указать расположение проекта, при необходимости. In the next page, enter MyExecRefsLib in the Name box to specify a name for the project, and specify the project location if desired.

Цукерберг рекомендует:  С++ - Количество символов в наибольшем слове строки

Выберите создать кнопку, чтобы создать клиентский проект. Choose the Create button to create the client project.

Чтобы создать C++ консольное приложение, которое ссылается на статической библиотеки в Visual Studio 2020 To create a C++ console app that references the static library in Visual Studio 2020

В строке меню выберите Файл > Создать > Проект. On the menu bar, choose File > New > Project.

В левой части новый проект диалоговое окно последовательно раскройте элементы установленные > Visual C++, а затем выберите Windows Desktop. In the left pane of the New Project dialog box, expand Installed > Visual C++, and then select Windows Desktop. В центральной области выберите мастер создания классических приложений Windows. In the center pane, select Windows Desktop Wizard.

Укажите имя проекта, например MyExecRefsLib, в поле Имя . Specify a name for the project—for example, MyExecRefsLib—in the Name box. В раскрывающемся списке рядом с полем Решениевыберите Добавить в решение. In the drop-down list next to Solution, select Add to Solution. Команда добавляет новый проект в решение, содержащее статическую библиотеку. The command adds the new project to the solution that contains the static library. Нажмите кнопку ОК . Choose the OK button.

В разделе тип приложениявыберите консольное приложение (.exe). Under Application type, select Console Application (.exe).

В разделе Дополнительные параметры, снимите флажок предкомпилированный заголовок «флажок». Under Additional Options, un-check the Precompiled header check box.

Выберите ОК для создания проекта. Choose OK to create the project.

Чтобы создать C++ консольное приложение, которое ссылается на статической библиотеки в Visual Studio 2015 To create a C++ console app that references the static library in Visual Studio 2015

В строке меню выберите Файл > Создать > Проект. On the menu bar, choose File > New > Project.

В новый проект диалогового окна разверните узел установленные > шаблоны > Visual C++ , и затем выберите Win32. In the New Project dialog box, expand Installed > Templates > Visual C++, and then select Win32. В центральной области выберите Консольное приложение Win32. In the center pane, select Win32 Console Application.

Укажите имя проекта, например MyExecRefsLib, в поле Имя . Specify a name for the project—for example, MyExecRefsLib—in the Name box. В раскрывающемся списке рядом с полем Решениевыберите Добавить в решение. In the drop-down list next to Solution, select Add to Solution. Команда добавляет новый проект в решение, содержащее статическую библиотеку. The command adds the new project to the solution that contains the static library. Нажмите кнопку ОК . Choose the OK button.

Нажмите кнопку Далее. Click Next.

Убедитесь, что консольное приложение выбран. Make sure Console application is selected. Затем проверьте пустой проект можно выбрать Готово. Then check the Empty Project box and choose Finish.

Использование функциональности из статической библиотеки в приложении Using the functionality from the static library in the app

Использование функциональности из статической библиотеки в приложении To use the functionality from the static library in the app

После создания консольного приложения будет создана пустая программа. After you create a console app, an empty program is created for you. Имя исходного файла будет совпадать с ранее выбранным именем. The name for the source file is the same as the name that you chose earlier. В этом примере он называется MyExecRefsLib.cpp . In the example, it’s named MyExecRefsLib.cpp .

Для использования математических процедур из статической библиотеки необходимо сослаться на эту библиотеку. Before you can use the math routines in the static library, you must reference it. Откройте контекстное меню для MyExecRefsLib в проекте обозревателе решенийи нажмите кнопку добавить > ссылку. Open the shortcut menu for the MyExecRefsLib project in Solution Explorer, and then choose Add > Reference.

В диалоговом окне Добавление ссылки перечислены библиотеки, на которые можно создать ссылку. The Add Reference dialog box lists the libraries that you can reference. Проекты вкладке перечислены все проекты текущего решения и все библиотеки, они ссылаются. The Projects tab lists the projects in the current solution and any libraries they reference. На вкладке Проекты установите флажок MathFuncsLib , а затем нажмите кнопку ОК . On the Projects tab, select the MathFuncsLib check box, and then choose the OK button.

Ссылка MathFuncsLib.h файла заголовка, необходимо изменить путь к каталогам включения. To reference the MathFuncsLib.h header file, you must modify the included directories path. Для этого в диалоговом окне Окна свойств библиотеки MyExecRefsLibпоследовательно разверните узлы Свойства конфигурации , C/C++ , а затем выберите Общие. In the Property Pages dialog box for MyExecRefsLib, expand the Configuration Properties node, expand the C/C++ node, and then select General. Рядом с полем Дополнительные каталоги включаемых файлов, укажите путь к MathFuncsLib или найдите его каталог. Next to Additional Include Directories, specify the path of the MathFuncsLib directory, or browse for it.

Чтобы найти путь к каталогу, откройте раскрывающийся список значений свойства и выберите Изменить. To browse for the directory path, open the property value drop-down list, and then choose Edit. В Дополнительные каталоги включаемых файлов диалоговое окно, в текстовом поле выберите пустую строку и нажмите кнопку с многоточием (. ) в конце строки. In the Additional Include Directories dialog box, in the text box, select a blank line and then choose the ellipsis button (. ) at the end of the line. В диалоговом окне Выбор каталога выберите каталог MathFuncsLib и нажмите кнопку Выбор папки , чтобы сохранить выбранное значение и закрыть диалоговое окно. In the Select Directory dialog box, select the MathFuncsLib directory and then choose Select Folder button to save your selection and close the dialog box. В диалоговом окне Дополнительные каталоги включаемых файлов , нажмите кнопку ОК , затем в диалоговом окне Окна свойств нажмите кнопку ОК для сохранения изменений в проект. In the Additional Include Directories dialog box, choose the OK button, and then in the Property Pages dialog box, choose the OK button to save your changes to the project.

Теперь вы можете использовать MyMathFuncs класс в этом приложении, включая #include «MathFuncsLib.h» заголовка в коде. You can now use the MyMathFuncs class in this app by including the #include «MathFuncsLib.h» header in your code. Замените содержимое файла MyExecRefsLib.cpp следующим кодом: Replace the contents of MyExecRefsLib.cpp with this code:

Соберите исполняемый файл, выбрав построения > построить решение в строке меню. Build the executable by choosing Build > Build Solution on the menu bar.

Запуск приложения Running the app

Запуск приложения To run the app

Убедитесь, что проект MyExecRefsLib выбран в качестве проекта по умолчанию, открыв контекстное меню для MyExecRefsLib в обозревателе решенийи выбрав пункт Назначить запускаемым проектом. Make sure that MyExecRefsLib is selected as the default project by opening the shortcut menu for MyExecRefsLib in Solution Explorer, and then choosing Set as StartUp Project.

Чтобы запустить проект, в строке меню выберите Отладка > Запуск без отладки. To run the project, on the menu bar, choose Debug > Start Without Debugging. Выходные данные должны иметь: The output should resemble:

C++ — Подключение сторонней библиотеки к проекту на С++

Самая актуальная документация по Visual Studio 2020: Документация по Visual Studio 2020.

В этом пошаговом руководстве описывается создание библиотеки динамической компоновки (DLL) для использования с приложением на C++. Библиотеки являются хорошим способом повторного использования кода. Вместо того чтобы каждый раз реализовывать одни и те же подпрограммы в каждом создаваемом приложении, их можно создать единожды и затем ссылаться на них из других приложений. Поместив код в библиотеку DLL, вы сэкономите место в каждом приложении, которое ссылается на этот код, а также сможете обновлять DLL без перекомпиляции всех приложений. Подробнее о библиотеках DLL см. в статье DLL в Visual C++.


В этом пошаговом руководстве рассматриваются следующие задачи:

создание проекта DLL;

добавление класса в DLL;

создание консольного приложения, использующего динамическую компоновку времени загрузки для ссылки на библиотеку DLL;

использование функциональности из класса в приложении;

В этом пошаговом руководстве будет создана библиотека DLL, которая может вызываться только из приложений, использующих соглашения о вызове C++. Сведения о создании библиотек DLL для использования с другими языками см. в статье Вызов функций библиотек DLL из приложений Visual Basic.

Это руководство предполагает знание основ языка C++.

Создание проекта библиотеки динамической компоновки (DLL)

В строке меню выберите Файл, Создать, Проект.

В левой области диалогового она Создать проект разверните Установленные, Шаблоны, Visual C++ и затем выберите Win32.

В центральной области выберите Консольное приложение Win32.

Укажите имя для проекта, например MathFuncsDll, в поле Имя. Укажите имя для решения, например DynamicLibrary, в поле Имя решения. Нажмите кнопку ОК.

На странице Обзор диалогового окна Мастер приложений Win32 нажмите кнопку Далее.

На странице Параметры приложения выберите в поле Тип приложения пункт DLL.

Нажмите кнопку Готово, чтобы создать проект.

Добавление класса в библиотеку динамической компоновки

Чтобы создать файл заголовка для нового класса, в меню Проект выберите пункт Добавить новый элемент. В диалоговом окне Добавить новый элемент в левой области в разделе Visual C++ выберите Код. В центральной области выберите Заголовочный файл (.h). Укажите имя для заголовка файла, например MathFuncsDll.h, и нажмите кнопку Добавить. Отобразится пустой файл заголовка.

Добавьте следующий код в начало файла заголовка:

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

Когда символ MATHFUNCSDLL_EXPORTS определен, символ MATHFUNCSDLL_API установит модификатор __declspec(dllexport) в объявлениях функций-членов в этом коде. Этот модификатор разрешает экспорт функции библиотекой DLL для использования ее другими приложениями. Если символ MATHFUNCSDLL_EXPORTS не определен, например, когда файл заголовка включен приложением, символ MATHFUNCSDLL_API определяет модификатор __declspec(dllimport) в объявлениях функций-членов. Этот модификатор оптимизирует импорт функции в приложении. По умолчанию шаблон нового проекта для библиотеки DLL добавляет символ PROJECTNAME _EXPORTS в список определенных символов для проекта DLL. В этом примере символ MATHFUNCSDLL_EXPORTS определяется при сборке проекта MathFuncsDll. Для получения дополнительной информации см. dllexport, dllimport.

Если проект DLL собирается в командной строке, воспользуйтесь параметром компилятора /D, чтобы определить символ MATHFUNCSDLL_EXPORTS.

В проекте MathFuncsDll в обозревателе решений в папке Исходные файлы откройте файл MathFuncsDll.cpp.

Реализуйте функциональность класса MyMathFuncs в исходном файле. Код должен выглядеть примерно следующим образом:

Скомпилируйте библиотеку динамической компоновки, выбрав Собрать решение в меню Сборка.

Примечание

При использовании выпуска Express, в котором не отображается меню Сборка, в строке меню выберите Сервис, Параметры, Расширенные параметры, чтобы включить это меню, а затем выберите Сборка, Собрать решение.

Примечание

При сборке проекта из командной строки используйте параметр компилятора /LD, указывающий на то, что выходной файл должен являться DLL-файлом. Для получения дополнительной информации см. /MD, /MT, /LD (использование библиотеки времени выполнения). Используйте параметр компилятора /EHsc для включения обработки исключений С++. Для получения дополнительной информации см. Параметр /EH (модель обработки исключений).

Создание приложения, ссылающегося на DLL

Чтобы создать приложение С++, которое будет ссылаться и использовать созданную ранее библиотеку DLL, в меню Файл выберите пункт Создать и затем пункт Проект.

В левой области в категории Visual C++ выберите Win32.

В центральной области выберите Консольное приложение Win32.

Укажите имя проекта, например MyExecRefsDll, в поле Имя. В раскрывающемся списке рядом с полем Решение выберите Добавить в решение. В результате новый проект будет добавлен в решение, содержащее библиотеку DLL. Нажмите кнопку ОК.

На странице Обзор диалогового окна Мастер приложений Win32 нажмите кнопку Далее.

На странице Параметры приложения выберите в поле Тип приложения пункт Консольное приложение.

На странице Параметры приложения в разделе Дополнительные параметры снимите флажок Предкомпилированный заголовок.

Нажмите кнопку Готово, чтобы создать проект.

Использование функциональности из библиотеки классов в приложении


После создания консольного приложения будет создана пустая программа. Имя исходного файла будет совпадать с ранее выбранным именем. В этом примере он имеет имя MyExecRefsDll.cpp.

Для использования в приложении математических процедур, созданных в библиотеке DLL, необходимо сослаться на эту библиотеку. Для этого в обозревателе решений выберите проект MyExecRefsDll, а затем в меню Проект выберите пункт Ссылки. В диалоговом окне Страницы свойств разверните узел Общие свойства, выберите .NET Framework и ссылки и нажмите кнопку Добавить новую ссылку. Дополнительные сведения о диалоговом окне Ссылки см. в разделе Добавление ссылок.

В диалоговом окне Добавление ссылки перечислены библиотеки, на которые можно создать ссылку. На вкладке Проект перечислены все проекты текущего решения и включенные в них библиотеки, если они есть. Установите флажок рядом с MathFuncsDll на вкладке Проекты, а затем нажмите кнопку ОК.

Для создания ссылки на файлы заголовка DLL необходимо изменить путь к каталогам включения. Для этого в диалоговом окне Окна свойств последовательно разверните узлы Свойства конфигурации и C/C++, а затем выберите Общие. В поле Дополнительные каталоги включаемых файлов укажите путь к месту размещения файла заголовка MathFuncsDll.h. Можно использовать относительный путь, например ..\MathFuncsDll\. Затем нажмите кнопку ОК.

Теперь класс MyMathFuncs можно использовать в приложении. Замените содержимое файла MyExecRefsDll.cpp следующим кодом.

Соберите исполняемый файл, выбрав команду Собрать решение в меню Сборка.

Запуск приложения

Убедитесь в том, что проект MyExecRefsDll выбран в качестве проекта по умолчанию. В обозревателе решений выберите MyExecRefsDll и затем в меню Проект выберите Назначить запускаемым проектом.

Чтобы запустить проект, в строке меню выберите Отладка, Запуск без отладки. Результат выполнения должен выглядеть примерно следующим образом:

a + b = 106,4
a — b = -91,6
a * b = 732,6
a / b = 0,0747475
Перехвачено исключение: b не может быть равно нулю!

C++ — Подключение сторонней библиотеки к проекту на С++

1. Добавляйте inlcude для вашего .h. Куда именно зависит от того где оно требуется и от использования прекомпиляции заголовков.

2. Используйте методы/классы которые определены в .h как требуется.

3. Добавляйте .lib в список файлов линкера. Если .lib прописана в .h то то может и не потребоваться. Если .lib использует какие либо другие библиотеки то их тоже потребуется добавить.

Никаких ссылок в C++ нет, это только для управляемых языков.

Наличие самой DLL для компиляции не требуется, но она должна быть доступна при выполнении программы, например поместите ее туда же куда и exe.

This posting is provided «AS IS» with no warranties, and confers no rights.

Использование в языке D сторонних библиотек

Утилита dub

Честно говоря, я до сих пор “плаваю” в опциях dmd, необходимых для компиляции и сборки приложения. Виной тому утилита dub, которая берет на себя все эти заботы и позволяет отложить изучение нюансов компиляции и сборки приложения на потом, когда это действительно станет необходимо. Кроме этого, эта полезная программка выполняет функции пакетного менеджера, обладая функционалом, аналогичным утилитам pip для python, npm для javascript и т.п.

Инициализация проекта

Для инициализации приложения с помощью утилиты dub надо создать каталог проекта, перейти в него и выполнить команду:

В результате будет создан файл dub.json, с помощью которого задается конфигурация и параметры сборки приложения. А также, подкаталог source, содержащий файл app.d с незамысловатым хелоуворлдом.
Сборка и/или запуск приложения производится этой же утилитой, запускаемой из корневого каталога проекта, то есть из каталога, содержащего файл dub.json . Чтобы скомпилировать, собрать и запустить хелоуворлд из файла app.d , достаточно выполнить команду dub .

Подключение сторонних пакетов (библиотек)

В терминах языка, библиотеки сторонних разработчиков на D, распространяемые в виде исходных кодов, называются пакеты. Утилита dub использует реестр пакетов, находящийся по следующему адресу. Использование библиотек, написанных с помощью C/C++ также возможно, но для этого необходимо подключение в проект специальных пакетов, называемых binding. Сама же библиотека должна быть установлена в системе. Например, libev, которая дальше будет задействована, устанавливается в debian подобных дистрибутивах linux следующим образом:

Для использования её в проекте на D нужен биндинг, который добрый человек уже сделал и разместил в выше названном реестре. Там же есть инструкция, какие изменения нужно внести в файл dub.json для использования libev в проекте. Все сводится к добавлению в раздел dependencies файла dub.json имени пакета, версии и, по необходимости, некоторых других параметров.
При следующем выполнении команды dub , все перечисленные в dependencies пакеты будут проверены и подгружены в случае их отсутствия.

Хелоуворлд с использованием libev

После выше описанных манипуляций проект готов к использованию фичей из libev . Ниже приведен код, который следует поместить в файл app.d , и если все прошло гладко, получим исполняемый файл, который будет радовать раз в секунду сообщением “Hello, World!” в консоле.

Что тут стоит отметить в плане использования сторонних библиотек в программах на D?
Во-первых, во второй строке подключается пакет-биндинг к libev . Во-вторых, функция обратного вызова cb_timer определена как extern(C) . Фактически её вызов будет происходить из недр подключенной библиотеки, а она у нас написана на С. Следовательно, соглашение о вызове cb_timer должно соответствовать вызову функций написанных на С.

Что можно сказать в целом, глядя на код? Не считая фичи языка D, позволившей определить cb_timer в теле функции main , код мало отличается от аналогичной программы на C. Это связано с тем, что пакеты-биндинги обычно содержат минимальную обвязку над вызовами функций из сишных библиотек. Часто для удобства делается еще один уровень обвязки, который предоставляет более читаемый код с использованием “синтаксического сахара” языка D. Например, аналогичный код мог бы выглядеть как-то так.

Кстати, код приведенный выше — реально существующий. Я попробовал сделать высокоуровневую обертку над libev , используя параметризованный класс для вотчеров. Получилось вроде неплохо. Если это будет кому-то интересно — в следующей статье расскажу об этом.

Upd: По использованию dub здесь есть неплохая статья, автор достаточно подробно описал основные возможности утилиты.

PS: Неплохо бы было уже сделать подсветку синтаксиса D в редакторе хабратопиков.

C++ — Подключение сторонней библиотеки к проекту на С++

Профиль
Группа: Участник
Сообщений: 541
Регистрация: 16.4.2009
Где: Ростов-на-Дону

Репутация: нет
Всего: 3

Greetings to all.
Пытался понять Как подключить библиотеку с C#( и платформы .NET в целом) в С++
Вот нашол в нете такой пример.

Примечание
Код
Библиотека на ШАРПЕ
namespace MyNamespace
<
public class MyClass
<
public static int MyMethod(string text)
<
MessageBox.Show(text);
return 0;
>
>
>
А это на С++
#include «MSCorEE.h»
void StartTheDotNetRuntime()
<
// Подключаем CLR
ICLRRuntimeHost *pClrHost = NULL;
HRESULT hr = CorBindToRuntimeEx(
NULL, L»wks», 0, CLSID_CLRRuntimeHost,
IID_ICLRRuntimeHost, (PVOID*)&pClrHost);
hr = pClrHost->Start();
// Теперь можно вызвать метод .Net библиотеки
DWORD dwRet = 0;
hr = pClrHost->ExecuteInDefaultAppDomain(
L»c:\\PathToYourManagedAssembly\\MyManagedAssembly.dll»,
L»MyNamespace.MyClass», L»MyMethod»,
L»MyParameter», &dwRet);
// Выгружаем CLR
hr = pClrHost->Stop();
// Убираем за собой
pClrHost->Release();
>
CorBindToRuntimeEx – возвращает указатель на интерфейс ICLRRuntimeHost.
ICLRRuntimeHost::Start – позволяет запустить CLR Runtime на выполнение или подключиться к уже запущенному экземпляру.
ICLRRuntimeHost::ExecuteInDefaultAppDomain – позволяет загрузить в CLR указанную библиотеку с управляемым кодом

Ноу меня выдаёт

Код
Error 3 error LNK2001: unresolved external symbol _CorBindToRuntimeEx@24 Main.obj С++MyLin


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

Я создавал всё на VS2008.

Это сообщение отредактировал(а) KuMa1104 — 28.10.2009, 21:23

Галактика – суровая штука. Чтобы в ней выжить, надо знать, где твое полотенце.

Время — штука относительная. а время обеда — ещё более относительная

Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118

jonie
Дата 28.10.2009, 22:30 (ссылка) | (нет голосов) Загрузка .

Профиль
Группа: Участник
Сообщений: 541
Регистрация: 16.4.2009
Где: Ростов-на-Дону

Репутация: нет
Всего: 3

Если использовать C++ Managed то возникает такая проблема.

Библиотека C++ Managed компилирую, всё работает

KuMa1104
Дата 28.10.2009, 22:55 (ссылка) | (нет голосов) Загрузка .
Код
using namespace System; // ограничемся простым случаем
class Class1
<
// TODO: Add your methods for this class here.

void fnc()
<
System::Console::WriteLine(«AAAAAAAAAAA»);
//cout

А вот исполняемый проект к которому я её подключаю

Код
#include
using namespace std;
#include «TedtLib2.h»
void main()
<
cout >a;

Как видите я ещё даже её не как не использовал.
А мне компилятор уже выдаёт ошибку.

Код
Error 1 error C2871: ‘System’ : a namespace with this name does not exist c:\documents and settings\макс\мои документы\visual studio 2008\projects\с++ lines\с++ lines\TedtLib2.h 7 С++ Lines

Добавлено @ 22:59
Насколько я понемю это от того что Обычный с++ знать не знает ничег об
namespace System но в проект на чистом с++ её не льзя подключить.

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

Это сообщение отредактировал(а) KuMa1104 — 28.10.2009, 23:04

Галактика – суровая штука. Чтобы в ней выжить, надо знать, где твое полотенце.

Время — штука относительная. а время обеда — ещё более относительная

Профиль
Группа: Участник
Сообщений: 541
Регистрация: 16.4.2009
Где: Ростов-на-Дону

Репутация: нет
Всего: 3

KuMa1104
Дата 28.10.2009, 23:19 (ссылка) | (нет голосов) Загрузка .
Код
#include «TedtLib2.h»

На чистом С++ это работает а с С++/CLR нет из за System ну незнает от её и всё тут(((

Может надо как то через .lib делать ?
Или результат такойже будет.

Это сообщение отредактировал(а) KuMa1104 — 28.10.2009, 23:21

Галактика – суровая штука. Чтобы в ней выжить, надо знать, где твое полотенце.

Время — штука относительная. а время обеда — ещё более относительная

Профиль
Группа: Участник
Сообщений: 541
Регистрация: 16.4.2009
Где: Ростов-на-Дону

Репутация: нет
Всего: 3

Сделал в виде библиотеки

Пытаюсь её подключить.

KuMa1104
Дата 28.10.2009, 23:37 (ссылка) | (нет голосов) Загрузка .
Код
#include
using namespace std;
#pragma comment (lib, » C:\\Documents and Settings\\Макс\\Мои документы\\Visual Studio 2008\\Projects\\TedtLib2\\Debug\\TedtLib2.dll»)
void main()
<
cout >a;
>


Код
Error 1 fatal error LNK1104: cannot open file ‘ C:\Documents and Settings\Макс\Мои документы\Visual Studio 2008\Projects\TedtLib2\Debug\TedtLib2.dll’ С++ Lines С++ Lines

Галактика – суровая штука. Чтобы в ней выжить, надо знать, где твое полотенце.

Время — штука относительная. а время обеда — ещё более относительная

Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

C++ — Подключение сторонней библиотеки к проекту на С++

Первая трудность: не могу подключить .dll к VSC++2005Express. Нашел подсказку в RSDN, но смотрю — в VS даже пунктов меню, указанных в подсказке не наблюдается. Достаточно implicit linking, .lib, .h имеются.

jonie
Дата 29.10.2009, 09:09 (ссылка) | (нет голосов) Загрузка .
1. Shang Tsung , 09.07.2007 12:14
Вряд ли смогу вам помочь с вашей проблемой (тем более, что я так и не понял, в чём она состоит ). Зато озадачу впросом: если вы всё равно собираетесь привлекать дельфовский Chart, то почему VSEE, а не C++ Builder?
2. DrAG0n , 09.07.2007 12:44
ну. у меня просто нет свежего билдера, есть более-менее свежий (и вроде легальный) Delphi. В билдере Chart можно использовать напрямую?

Добавление от 09.07.2007 13:15:

обнаружил такую штуку: #pragma comment(lib,»MyDll.lib»)

буду пробовать

3. Sh.M.V , 09.07.2007 13:55
DrAG0n
В билдере Chart можно использовать напрямую?
можно
4. DrAG0n , 10.07.2007 06:23
В общем, через #pragma не получилось. Зато потом на сайте Intel нашел:

IntelR Math Kernel Library (IntelR MKL) for Windows*
Compiling and Linking with Microsoft* Visual C/C++*

The following provides hints for linking your program with IntelR MKL from the Microsoft* Visual C/C++*:

* * IntelR MKL 9.0 with Microsoft* Visual C++* .NET 2003 or Microsoft* Visual C++* 2005
* * IntelR MKL 8.1 with Microsoft* Visual C++* 6.0

IntelR MKL 9.0 with Microsoft* Visual C++* .NET 2003 or Microsoft* Visual C++* 2005

1. Select View > Solution Explorer (and make sure this window is active).
2. Select Tools > Options > Projects > VC++ Directories.
3. In the drop down menu titled Show directories for:, select Include Files, and then type in the directory for the Intel MKL include files (e.g. default: C:\Program Files\Intel\MKL\9.0\include).
4. In the drop down menu titled Show directories for:, select Library Files, and then type in the directory for the Intel MKL library files (e.g. default: C:\Program Files\Intel\MKL\9.0\ia32\lib).
5. In the drop down menu titled Show directories for:, select Executable Files, and then type in the directory for the Intel MKL executable files (e.g. default: C:\Program Files\Intel\MKL\9.0\ia32\bin).
6. On the main toolbar select Project > Properties > Configuration Properties > Linker > Input and in the «Additional Dependencies» line, add the libraries you require (e.g. mkl_c.lib).

IntelR MKL 8.1 with Microsoft* Visual C++* 6.0

In Project Settings, add the location (path) of Intel MKL sub-library in the link properties, for example, in Microsoft Visual Studio/Microsoft Visual C++ 6.0 with Intel MKL 8.1:

1. Select Project > Settings.
2. Select the Link tab.
3. In the Category drop-down menu, select Input.
4. In the Object/library modules section add mkl_c.lib or mkl_s.lib
* Note: If you need LAPACK support you must also add mkl_lapack library.
5. You must also add the library path to the location of these libraries. In the Additional library path section, add the location of the Intel MKL sub-libraries. For example, on an IA32 system, you would add C:\Program Files\intel\MKL\8.1\ia32\lib (for the default install location).

А потом и с IMKL не получилось, в результате скачал ACML (важно! которая для ifort) и без проблем ее подключил согласно вышенаписанному.

Теперь проблема подключить это счастье к Delphi — пока не нашел, как. DCU — без проблем. Dll — . Параллельно ищу Builder.

Добавление от 10.07.2007 08:47:

А может быть для Visual C есть какой-нибудь похожий на Chart компонент? Мне нужно рисовать график (сплошная кривая), наносить экспериментальные точки, уметь выбирать точки и масштабировать всяко. Ну, рисовать сетку, оси, подписи к точкам. Видимо, этого будет достаточно.

5. qq1 , 10.07.2007 10:26
DrAG0n
Теперь проблема подключить это счастье к Delphi — пока не нашел, как. DCU — без проблем. Dll — . Параллельно ищу Builder.

DCU без исходника, подключить не всегда возможно. Могут быть проблемы с версиями и зависимостями. Наверное.

DLL к Delphi, точнее функции из DLL подключаются элементарно. Для этого в uses добавляется соответствующий, тривиальный PAS файл.

Например, подключаем QueryPerformanceFrequency из kernel32.dll

Добавление от 10.07.2007 10:41:

Ой. Точнее, библиотека не обязательна. Это я по привычке. Можно и так:

6. Shang Tsung , 10.07.2007 12:41
DrAG0n
А может быть для Visual C есть какой-нибудь похожий на Chart компонент?
К сожалению, я не знаю, каков из себя этот Chart, но для построения диаграмм есть довольно много ActiveX-компонентов. ActiveX, как родную для MS технологию, в VS будет использовать проще по любому.

Мне нужно рисовать график (сплошная кривая), наносить экспериментальные точки, уметь выбирать точки и масштабировать всяко. Ну, рисовать сетку, оси, подписи к точкам. Видимо, этого будет достаточно.
То есть возможностей построения графиков в MS Excel вам хватает? Тогда берите MS Office Chart.

7. DrAG0n , 10.07.2007 15:31
он будет работать без установки офиса?

Я нашел кучу компонентов для графиков, но они или платные, или под C#, или и то и другое.

8. geoka , 10.07.2007 17:42
DrAG0n
Как вариант:
Если воспользоваться mingw, то есть большая вероятность, что ничего переписывать не придется. Для рисования графиков можно пользоваться gnuplot (есть для винды тоже). А скрипт (либо данные для скрипта) gnuplot’а выводить вашей программой в stdout, либо в файл, который потом скармливать gnuplot’у.
9. DrAG0n , 11.07.2007 07:56
мне надо еще ползать по графику, выбирать/настраивать/исключать точки и пересчитывать матричную коррекцию.

В общем, сейчас мне думается следующее: на VS делать консольную решалку, которой передаю текстовые задачи и получаю текстовые же решения. Все остальное пишу на Delphi (дополнительный +: узнаю дельфи подробнее, а то студентам уже 3й год за 1 семестр успеваю рассказать все, что сам знаю по Delphi ).

Возникает новый вопрос: как проще всего из Delphi обращаться к Access’овским .mdb файлам (доисторической версии, еще Office 97).


10. Alex_UAN , 11.07.2007 08:03
Только хотел создать новую тему, как увидел эту — передо мной стоит такая же проблема — как к проекту, написанному на Visual C++ 2003 подключить dll-ку, которая является элементом ActiveX, написанном на Делфи? (мне просто нужно экспортирвать функции, т.е. использовать ее как обычную библиотеку)
11. DrAG0n , 11.07.2007 09:55
Alex_UAN
Как подключить просто .dll-ку — знаю, как дельфевскую — пока нет — от этой проблемы я ушел.

Продолжая изучать азбуку, задался вопросом: что перспективнее — ADO, BDE или ODBC для доступа к .mdb файлам?

12. Alex_UAN , 11.07.2007 11:01
DrAG0n
А можно хотя бы кратко описать, как подключается обычная dll?
Так ведь разницы на чем сделана dll нет? Или я ошибаюсь?
13. DrAG0n , 11.07.2007 15:02
Ну, по крайней мере, в моем способе нужен .lib файл и .h — заголовок:

1. Select View > Solution Explorer (and make sure this window is active).
2. Select Tools > Options > Projects > VC++ Directories.
3. In the drop down menu titled Show directories for:, select Include Files, and then type in the directory for the (. ) include files
4. In the drop down menu titled Show directories for:, select Library Files, and then type in the directory for the library files
5. In the drop down menu titled Show directories for:, select Executable Files, and then type in the directory for the executable files
6. On the main toolbar select Project > Properties > Configuration Properties > Linker > Input and in the «Additional Dependencies» line, add the libraries you require (e.g. mkl_c.lib).

14. nenin , 11.07.2007 20:18
DrAG0n, так, чисто на всякий случай: mingw(gcc)+code::blocks — минимальные затраты на портирование с Linux и FLTK — простенькое API, имеются компоненты для построения графиков. Если база нужна, то sqlite прикрутить можно.

Добавление от 11.07.2007 20:20:

цитата: geoka:
DrAG0n
Как вариант:
Если воспользоваться mingw, то есть большая вероятность, что ничего переписывать не придется. Для рисования графиков можно пользоваться gnuplot (есть для винды тоже). А скрипт (либо данные для скрипта) gnuplot’а выводить вашей программой в stdout, либо в файл, который потом скармливать gnuplot’у.

C++ — Подключение сторонней библиотеки к проекту на С++

1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Работа с нативными dll библиотеками в C#

В процессе разработки программного обеспечения далеко не всегда достаточно собственных наработок. Чаще всего проект содержит те или иные сторонние библиотеки.

Очень многие из них не являются .NET сборками и предназначены для работы непосредственно в среде Windows. Но, к счастью, в .NET Framework существует удобный механизм, который позволяет интегрировать обычные Windows dll библиотеки в программные проекты на .NET языках. При этом C# не исключение.

Рассмотрим простой пример. Подключим библиотеку, написанную на C++, к программе на C#. В качестве примера воспользуемся библиотекой, которая была разработана ранее для работы с Delphi [1].

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

Механизм подключения предельно прост.

Вначале скопируем библиотеку в папку с программой или подключим её к проекту с указанием настройки копирования в выходной каталог «Копировать всегда» (в этом случае файл библиотеки будет добавляться в папку со скомпилированной программой автоматически).

Использование DLL в программе на Visual C++

Автор: Александр Шаргин


Версия текста: 2.0

Многие знают, что существует два основных способа подключить DLL к программе — явный и неявный.

При неявном подключении (implicit linking) линкеру передается библиотека импорта (обычно имеет расширение lib), содержащая список переменных и функций DLL, которые могут использовать приложения. Обнаружив, что программа обращается хотя бы к одной из них, линкер добавляет в целевой exe-файл таблицу импорта . Таблица импорта содержит список всех DLL, которые использует программа, с указанием конкретных переменных и функций, к которым она обращается. Позже, когда exe-файл будет запущен, загрузчик проецирует все DLL, перечисленные в таблице импорта, на адресное пространство процесса; в случае неудачи весь процесс немедленно завершается.

При явном подключении (explicit linking) приложение вызывает функцию LoadLibrary, чтобы загрузить DLL, затем использует функцию GetProcAddress, чтобы получить указатели на требуемые функции (или переменные), а по окончании работы с ними вызывает FreeLibrary, чтобы выгрузить библиотеку и освободить занимаемые ею ресурсы.

Каждый из способов имеет свои достоинства и недостатки. В случае неявного подключения все библиотеки, используемые приложением, загружаются в момент его запуска и остаются в памяти до его завершения (даже если другие запущенные приложения их не используют). Это может привести к нерациональному расходу памяти, а также заметно увеличить время загрузки приложения, если оно использует очень много различных библиотек. Кроме того, если хотя бы одна из неявно подключаемых библиотек отсутствует, работа приложения будет немедленно завершена. Явный метод лишен этих недостатков, но делает программирование более неудобным, поскольку требуется следить за своевременными вызовами LoadLibrary и соответствующими им вызовами FreeLibrary, а также получать адрес каждой функции через вызов GetProcAddress.

В Visual C++ 6.0 появился еще один способ подключения DLL, сочетающий в себе почти все достоинства двух рассмотренных ранее методов — отложенная загрузка DLL (delay-load DLL). Отложенная загрузка не требует поддержки со стороны операционной системы (а значит будет работать даже под Windows 95), а реализуется линкером Visual C++ 6.0. При отложенной загрузке DLL загружается только тогда, когда приложение обращается к одной из содержащихся в ней функций. Это происходит незаметно для программиста (то есть вызывать LoadLibrary/GetProcAddress не требуется). После того как работа с функциями библиотеки завершена, ее можно оставить в памяти или выгрузить посредством функции __FUnloadDelayLoadedDLL. Вызов этой функции — единственная модификация кода, которую может потребоваться сделать программисту (по сравнению с неявным подключением DLL). Если требуемая DLL не обнаружена, приложение аварийно завершается, но и здесь ситуацию можно исправить, перехватив исключение с помощью конструкции __try/__except. Как видим, отложенная загрузка DLL — весьма удобное средство для программиста.

Теперь рассмотрим, как каждый из перечисленных методов используется на практике. Для этого будем считать, что у нас есть библиотека MyDll.dll, которая экспортирует переменную Var, функцию Function и класс Class. Их объявления содержатся в заголовочном файле MyDll.h, который выглядит следующим образом:

Кроме того, будем считать, что библиотека импорта содержится в файле MyDll.lib.

Неявное подключение

Это наиболее простой метод подключения DLL к нашей программе. Все, что нам нужно — это передать линкеру имя библиотеки импорта, чтобы он использовал ее в процессе сборки. Сделать это можно различными способами.

Во-первых, можно непосредственно добавить файл MyDll.lib в проект посредством команды Project->Add to project->Files. Во-вторых, можно указать имя библиотеки импорта в опциях линкера. Для этого откройте окно настроек проекта (Project->Settings. ) и добавьте в поле Object/Library modules на вкладке Link имя MyDll.lib. Наконец, можно встроить ссылку на библиотеку импорта прямо в исходный код программы. Для этого используется директива #pragma c ключем comment. В нашем случае необходимо вставить в программу строчку:

Теперь можно использовать в программе любые переменные, функции и классы, содержащиеся в DLL, как если бы они находились в статической библиотеке. Например:

Явное подключение


Загрузка DLL

Как уже говорилось ранее, при явном подключении DLL программист должен сам позаботиться о загрузке библиотеки перед ее использованием. Для этого используется функция LoadLibrary, которая получает имя библиотеки и возвращает ее дескриптор. Дескриптор необходимо сохранить в переменной, так как он будет использоваться всеми остальными функциями, предназначенными для работы с DLL.

В нашем примере загрузка DLL выглядит так.

Вызов функций

После того как библиотека загружена, адрес любой из содержащихся в ней функций можно получить с помощью GetProcAddress, которой необходимо передать дескриптор библиотеки и имя функции. Затем функцию из DLL можно вызывать, как обычно. Например:

Обратите внимание на приведение указателя к ссылке на тип FARPROC. FARPROC — это указатель на функцию, которая не принимает параметров и возвращает int. Именно такой указатель возвращает функция GetProcAddress. Приведение типа необходимо, чтобы умиротворить компилятор, который строго следит за соответствием типов параметров оператора присваивания. Альтернативный подход заключается в использовании оператора typedef с последующим приведением значения, возвращаемого GetProcAddress, к указателю на функцию с нужным прототипом.


Доступ к переменным

Хотя это не всегда очевидно из документации, получить указатель на переменную из DLL можно, используя все ту же функцию GetProcAddress. В нашем примере это выглядит так.

Использование классов

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

Однако предположим, что у нас нет доступа к исходным кодам библиотеки, содержащей класс, а использование других типов подключения DLL по каким-то причинам невозможно. Классом удастся воспользоваться и в этом случае, но для достижения цели придется проделать дополнительную работу.

Сначала задумаемся, почему объекты класса из явно подключаемой библиотеки нельзя использовать, как обычно. Дело в том, что при создании объекта класса компилятор генерирует вызов его конструктора. Но линкер не может разрешить этот вызов, поскольку адрес конструктора будет известен только в процессе выполнения программы. В результате сборка программы закончится неудачно. Такая же проблема возникает при вызове невиртуальных методов класса. С другой стороны, вызов виртуальных методов возможен, так как он осуществляется через таблицу виртуальных функций (vtable). Так, следующий фрагмент откомпилируется и слинкуется нормально (хотя, конечно, вызовет ошибку в процессе выполнения):

Приведенные выше рассуждения подсказывают решение проблемы. Коль скоро неявный вызов конструктра невозможен, мы можем вызвать его вручную, предварительно получив его адрес и выделив память под объект. Затем можно вызывать невиртуальные методы, получая их адреса с помощью GetProcAddress. Виртуальные методы можно вызывать, как обычно. Кроме того, необходимо не забыть вручную вызвать деструктор объекта, прежде чем выделенная для него память будет освобождена.

Продемонстрирую все сказанное на примере. Сначала мы выделяем память для объекта и вызываем для него конструктор. Память можно выделить как на стеке, так и в куче (с помощью оператора new). Рассмотрим оба варианта.

Обратите внимание на использование операторов .* и ->* для вызова функции-члена класса по указателю на нее. Этими операторами мы будем пользоваться и дальше.

ПРИМЕЧАНИЕ

Как правило, имена функций, экспортируемых из DLL, искажаются линкером. Поэтому вместо понятного имени, такого как «Constructor», получается совершенно нечитабельное имя вида «??0Class@@QAE@XZ». В рассматриваемом примере я назначил переменным и функциям нормальные имена при помощи def-файла следующего содержания:

Невиртуальные методы класса вызываются так же, как и конструктор, например:

Виртуальные методы вызываются непосредственно (как это делается для обычных классов). Хотя DLL и экспортирует их, явно получать их адреса с помощью GetProcAddress не требуется. Отсюда следует вывод: если все методы класса являются виртуальными, использование объектов класса из явно подключаемой библиотеки практически ничем не отличается от использования объектов любого другого класса. Разница только в том, что конструктор и деструктор для таких объектов придется вызывать вручную.

В нашем примере виртуальная функция вызывается так.

После того, как работа с объектом завершена, его нужно уничтожить, вызвав для него деструктор. Если объект был создан на стеке, деструктор необходимо вызвать до его выхода из области видимости, иначе возможны неприятные последствия (например, утечки памяти). Если объект был распределен при помощи new, его необходимо уничтожить перед вызовом delete. В нашем примере это выглядит так.

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

Выгрузка библиотеки

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

Отложенная загрузка


Использование отложенной загрузки

Чтобы линкер мог встроить в программу функцию отложенной загрузки, ему необходимо передать библиотеку импорта DLL, а также статическую библиотеку Delayimp.lib, в которой содержатся вспомогательные функции механизма отложенной загрузки. Сделать это можно любым из способов, которые обсуждались в разделе о неявном подключении. Кроме того, нужно передать линкеру ключ /DELAYLOAD: , сообщающий о нашем желании отложить загрузку DLL до фактического обращения к одной из ее функций. Этот ключ можно добавить в настройки проекта или встроить прямо в исходный код программы, используя директиву #pragma. Вот как это выглядит в нашем примере.

Вот и все. Теперь можно использовать функции и классы DLL прозрачно, как и в случае с неявным подключением. Единственная проблема возникает с переменными: их невозможно использовать напрямую. Дело в том, что при обращении к одной из функций в DLL мы на самом деле вызываем функцию __delayLoadHelper, которая и выполняет загрузку DLL (если она еще не загружена), затем получает адрес функции с помощью GetProcAddress и перенаправляет все последующие вызовы функции по этому адресу. Но при обращении к переменной вызова функции не происходит, а значит использовать __delayLoadHelper не удается.

Проблема решается путем явного использования GetProcAddress при работе с переменными. Если DLL еще не загружена, ее придется загрузить явно с помощью LoadLibrary. Но если мы уже обращались к ее функциям и точно знаем, что она находится в памяти, мы можем получить ее дескриптор с помощью функции GetModuleHandle, которой необходимо передать имя DLL. В нашем примере это выглядит так.

Выгрузка библиотеки

Итак, мы установили, что при использовании отложенной загрузки DLL грузится в память, когда происходит обращение к одной из ее функций. Но в последствии нам может потребоваться выгрузить ее, чтобы не занимать зря системные ресурсы. Специально для этого предназначена функция __FUnloadDelayLoadedDLL, объявленная в файле Delayimp.h. Если вы планируете использовать ее, вам нужно задать еще один ключ линкера — /DELAY:UNLOAD. Например:

Имя, которое вы передаете функции __FUnloadDelayLoadedDLL, должно в точности соответствовать имени, заданному в ключе /DELAYLOAD. Если, к примеру, передать ей «MYLIB.DLL» или «mylib.dll», библиотека останется в памяти.

ПРЕДУПРЕЖДЕНИЕ

Не используйте FreeLibrary, чтобы выгрузить DLL с отложенной загрузкой.

Обработка исключений

Как я уже говорил, в случае ошибки функция __delayLoadHelper возбуждает исключение. Если нужная DLL не обнаружена, возбуждается исключение с кодом VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND). Если в DLL не обнаружена требуемая функция, исключение будет иметь код VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND).

ПРИМЕЧАНИЕ

VcppException — это макрос, который используется для формирования кода ошибки в подсистеме Visual C++. Первый параметр задает «степень серьезности» ошибки, а второй — код исключения.

И то, и другое исключение можно обработать, используя механизм структурной обработки исключений. Для этого нужно написать фильтр , реагирующий на приведенные коды исключения, а также обработчик исключения. В простейшем случае они могут выглядеть так.

Написанный вами фильтр исключений может также получить дополнительную информацию с помощью функции GetExceptionInformation. Эта функция возвращает указатель на структуру EXCEPTION_POINTERS. В ней содержится поле ExceptionRecord — указатель на структуру EXCEPTION_RECORD. А структура EXCEPTION_RECORD в свою очередь содержит поле ExceptionInformation[0], в которое __delayLoadHelper помещает указатель на структуру DelayLoadInfo, содержащую дополнительную информацию. Эта структура объявлена следующим образом (файл Delayimp.h).

В частности, вы можете извлечь из нее имя DLL (поле szDll), а также имя или порядковый номер функции, вызов которой привел к исключению (поле dlp).

Функции-ловушки

Если возможностей обработки исключений вам недостаточно, вы можете пойти еще дальше и вмешаться в работу __delayLoadHelper, используя функции-ловушки. В Visual C++ предусмотрено две таких функции: одна из них получает уведомления, вторая — сообщения об ошибках. Чтобы функция __delayLoadHelper могла обращаться к ним, их адреса нужно записать в глобальные переменные __pfnDliNotifyHook и __pfnDliFailureHook соответственно. Иногда обе функции объединяют в одну.

Функции-ловушки должны иметь следующий прототип:

Первый параметр функции содержит код уведомления или ошибки, второй — указатель на уже знакомую нам структуру DelayLoadInfo. Все возможные коды уведомления описаны в файле Delayimp.h при помощи следующего перечисления:

В качестве примера приведу текст функции-ловушки, которая подменяет вызов функции SomeFunc на вызов функции YetAnotherFunc.

Цукерберг рекомендует:  CSS Grid и модульные сетки
Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих