Лабораторная работа 15 Использование библиотек динамической компоновки (DLL) Выполнив эту лабораторную работу, Вы сможете: познакомиться с понятием библиотека динамической компоновки; проектировать приложения с использованием библиотек динамической компоновки; создавать библиотеки динамической компоновки; подключать содержимое библиотек динамической компоновки к приложению. Понятие библиотеки динамической компоновки При выполнении приложения Windows могут использовать средства, которые находятся в библиотеках динамической компоновки (Dynamic Link Library – DLL).
Библиотека динамической компоновки не является исполняемой программой, но содержащийся в ней код может быть вызван из приложения или из другой DLL. С точки зрения разделения кода библиотека похожа на обычный программный модуль. В библиотеке, как и в модуле, удобно размещать общий код, а также секционировать большой проект.
Однако принципиальное отличие состоит в том, что код модуля подключается к проекту статически – на этапе компиляции. При этом выполняется проверка кода модуля на правильность, а в исполняемый файл приложения попадает весь используемый код модуля, например, процедуры и функции. Библиотека динамической компоновки подключается к приложению динамически – на этапе его выполнения.
СОЗДАНИЕ DLL C# | КАК ПОДКЛЮЧИТЬ DLL | C# ПЛЮШКИ
При компиляции проекта компоновщик только настраивает в исполняемом файле специальные таблицы, занося туда информацию о внешних процедурах и функциях. Сами же библиотеки загружаются после запуска вызывающего их приложения. Следовательно, использование библиотек динамической компоновки имеет следующие достоинства: Экономия оперативной памяти – если несколько одновременно выполняемых приложений используют общую DLL, то она будет загружена в оперативную память только один раз; Секционирование кода – большое приложение можно разделить на несколько секций (частей), одна из которых будет собственно приложением, а другие оформленные как библиотеки динамической компоновки; Обмен кодом между различными средами программирования – библиотека, созданная в одной инструментальной среде разработки может быть применена в приложениях, разработанных средствами других инструментальных сред. Библиотека динамической компоновки (DLL) – специально оформленный программный модуль, динамически подключаемый к приложению. Динамически подключаемый программный модуль – модуль, подключаемый к основному приложению во время выполнения приложения.
поиск по имени procedure Searsh_Fam(Fam:string;mas:array of string;var num_fam:integer); где Fam – фамилия для поиска, mas – массив среди, которого нужно искать, num_fam – номер нужной фамилии в массиве поиск по дисциплине procedure searsh_subject(subject:array of string; mark:string; var fams:array of integer); где Subject – это массив оценок по предмету. Создание библиотек динамической компоновки Теперь пришло время рассмотреть создание библиотек динамической компоновки более конкретно.
Для этого выполните следующее здание. Задание 3 Создайте библиотеку динамической компоновки. Перед тем, как начать оформление необходимых подпрограмм необходимо выбрать нужный тип документа выбрав пункт New меню Файл и выбрать тип DLL (см.Рис. 1). Рис. 1 Окно выбоа типа приложения Структура библиотеки динамической компоновки
Многофайловый проект | Изучение С++ для начинающих. Урок #139
После выбора данного типа приложения окно рабочего модуля библиотеки динамической компоновки выглядит следующим образом:
Рис. 2 Окно проекта библиотеки динамической компоновки Список экспортируемых функций В библиотеку динамической компоновки могут быть включены не только подпрограммы, которые используются вне данной библиотеки, но и вспомогательные.
Поэтому существует раздел (после описания всех подпрограмм и перед разделом инициализации) Exports, где перечисляются через запятую имена тех подпрограмм, которые доступны вне данной библиотеки. Например, см.Рис. 3. Описание подпрограмм библиотеки. Рис. 3 Внутренние и внешние функции Задание 3 Реализуйте все необходимые функции для «Задачи 1» в только что созданной библиотеке динамической компоновки, сохранив ее под именем Task_11_1.dll.
Создание клиентских программ Как уже говорилось, после создания библиотеки динамической компоновки необходимо подключить ее к клиентскому приложению. Задание 4 Скопируйте библиотеку динамической компановки Task_11_1.dll в папку с клиентским приложением; Откройте проект клиентского приложения Task_11_1 и, используя комментарии, разберитесь, как подключена библиотека динамической компоновки и как работает данное приложение.
Проверьте работоспособность данного приложения. Создайте библиотеку динамической компоновки для «Задачи 2» и подключите ее к клиентскому приложению из папки Task_11_2. Решение задач Задание 5 Модифицируйте проект Task_11_1 так, чтобы он позволял осуществлять поиск отличников. Пригласите преподавателя и продемонстрируйте ему оба приложения.
Контрольные задания Выполните варианты заданий, указанные преподавателем. Примечание В процессе выполнения задания можно использовать содержимое библиотек динамической компоновки, созданных в процессе выполнения лабораторной работы. Вариант 1 Создайте приложение с использованием библиотек динамической компоновки регистрации и перерегистрации автомобилей и возможностью получать отчет о тех, у кого закончился срок технического осмотра (библиотека динамической компоновки должна содержать подпрограммы поиска автомобиля по его номеру и поиска списока автомобилей с истекшим сроком ТО). Вариант 2 Создайте приложение с использованием библиотек динамической компоновки «Электронный прайс-лист», который позволил бы отыскивать необходимые лекарства и отслеживал их срок годности, составляя отчет в файл (библиотека динамической компоновки должна содержать подпрограммы поиска лекарства по его названию и поиска список лекарств с истекшим сроком годности). Вариант 3 Создайте приложение с использованием библиотек динамической компоновки «Электроэкономка», позволяющее начислять должникам по оплате за электроэнергию пеню каждый месяц и создавать отчет о сумме долга на текущий момент (библиотека динамической компоновки должна содержать подпрограммы поиска жителя по его фамилии и поиска списока жителей с наличием задолжностей).
Резюме Библиотека динамической компоновки (DLL) – специально оформленный программный модуль, динамически подключаемый к приложению. Динамически подключаемый программный модуль подключаемый к основному приложению во время выполнения приложения. Библиотека динамической компоновки подключается к приложению динамически – на этапе его выполнения.
Использование библиотек динамической компоновки имеет следующие достоинства: Экономия оперативной памяти – если несколько одновременно выполняемых приложений используют общую DLL, то она будет загружена в оперативную память только один раз; Секционирование кода – большое приложение можно разделить на несколько секций (частей), одна из которых будет собственно приложением, а другие оформленны как библиотеки динамической компоновки; Обмен кодом между различными средами программирования – библиотека, созданная в одной инструментальной среде разработки может быть применена в приложениях, разработанных средствами других инструментальных сред. Спроектировать библиотеку динамической компоновки можно, ответив на следующие вопросы: Какие возможности должно реализовывать будущие приложение?
Какие объекты присутствуют в данном приложении? Каких из них непосредственно касаются перечисленных возможности? Какие возможности имеют общий характер, а какие частный? Какие возможности стоит реализовать в библиотеке динамической компоновки, а какие в клиентском приложении?
После того, как Вы определились с набором возможностей библиотеки динамической компоновки, необходимо разработать интерфейс подпрограмм, реализующих данные возможности. Интерфейс подпрограммы – формат заголовка подпрограммы. Создание библиотеки динамической компоновки осуществляется путем создания соответствующего типа приложения.
Контрольные вопросы 1. Что такое библиотека динамической компоновки? 2. В чем отличие библиотеки динамической компоновки от программного модуля? 3. Что означает выражение: « модуль связан с клиентским приложением динамически»? «Статически»? 4. Какое расширение имеет файл библиотеки динамической компоновки? 5. Можно ли отредактировать файл библиотеки динамической компоновки?
Проекта библиотеки динамической компоновки? 6. В чем состоит технология создания библиотеки динамической компоновки? 7. Как определить, что данная подпрограмма может использоваться в других библиотеках динамической компоновки или приложениях, а другая нет?
Источник: studfile.net
Плагины, какие они бывают.
Как называется дополнительный программный модуль динамически подключаемый к основной программе
При создании приложения для него определяется набор сборок, которые будут использоваться. В проекте указываются ссылки на эти сборки, и когда приложение выполняется, при обращении к функционалу этих сборок они автоматически подгружаются.
Но также мы можем сами динамически подгружать другие сборки, на которые в проекте нет ссылок.
Для управления сборками в пространстве имен System.Reflection имеется класс Assembly . С его помощью можно загружать сборку, исследовать ее.
Чтобы динамически загрузить сборку в приложение, надо использовать статические методы Assembly.LoadFrom() или Assembly.Load() .
Метод LoadFrom() принимает в качестве параметра путь к сборке.
Допустим, у нас есть два проекта:
Пусть в проекте MyApp, который компилируется в сборку MyApp.dll, имеется файл Program.cs со следующим кодом:
Person tom = new Person(«Tom»); Console.WriteLine($»Hello, «); class Person < public string Name < get; >public Person(string name) => Name = name; >
В другом проект исследуем сборку MyApp.dll на наличие в ней различных типов:
using System.Reflection; Assembly asm = Assembly.LoadFrom(«MyApp.dll»); Console.WriteLine(asm.FullName); // получаем все типы из сборки MyApp.dll Type[] types = asm.GetTypes(); foreach (Type t in types)
В данном случае для исследования указывается сборка MyApp.dll. Здесь использован относительный путь, так как сборка находится в одной папке с приложением — в проекте в каталоге bin/Debug/net6.x . Можно в принципе в качестве имени указать и имя текущего приложение. В этом случае программа будет исследовать саму себя. В любом случае стоит учитывать, что загрузке подлежат (по крайней мере в .NET 6.0) сборки с расширением dll, но не exe.
И в моем случае я получу следующий консольный вывод:
MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null EmbeddedAttribute NullableAttribute NullableContextAttribute Program Person
Как видно из вывода, полное название сборки: MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null . А сама сборка MyApp.dll содержит пять типов — кроме класса Person и неявно определяемого класса Program добавляется еще три автоматически генерируемых класса.
Метод Load() действует аналогично, только в качестве его параметра передается дружественное имя сборки, которое нередко совпадает с именем приложения: Assembly asm = Assembly.Load(«MyApp»);
Получив все типы сборки с помощью метода GetTypes() , мы опять же можем применить к каждому типу все те методы, которые были рассмотрены в прошлой теме.
Позднее связывание
С помощью динамической загрузки мы можем реализовать технологию позднего связывания. Позднее связывание позволяет создавать экземпляры некоторого типа, а также использовать его во время выполнения приложения.
Использование позднего связывания менее безопасно в том плане, что при жестком кодировании всех типов (ранее связывание) на этапе компиляции мы можем отследить многие ошибки. В то же время позднее связывание позволяет создавать расширяемые приложения, когда дополнительный функционал программы неизвестен, и его могут разработать и подключить сторонние разработчики.
Ключевую роль в позднем связывании играет класс System.Activator . С помощью его статического метода Activator.CreateInstance() можно создавать экземпляры заданного типа.
Например, динамически загрузим сборку и вызовем у ней некоторый метод. Допустим, загружаемая сборка MyApp.exe представляет следующую программу:
class Program < static void Main(string[] args) < var number = 5; var result = Square(number); Console.WriteLine($»Квадрат равен «); > static int Square(int n) => n * n; >
В данном случае мы явным образом определили класс Program с методом Main. И кроме того, в классе Program определен статический метод Square, который в качестве параметра принимает число и возвращает его квадрат.
Теперь динамически подключим сборку с этой программой в другой программе и вызовем ее методы.
Пусть наша основная программа будет выглядеть так:
using System.Reflection; Assembly asm = Assembly.LoadFrom(«MyApp.dll»); Type? t = asm.GetType(«Program»); if (t is not null) < // получаем метод Square MethodInfo? square = t.GetMethod(«Square», BindingFlags.NonPublic | BindingFlags.Static); // вызываем метод, передаем ему значения для параметров и получаем результат object? result = square?.Invoke(null, new object[] < 7 >); Console.WriteLine(result); // 49 >
Сначала получаем ссылку на исследуемую сборку в переменную asm:
Assembly asm = Assembly.LoadFrom(«MyApp.dll»)
Затем с помощью метода GetType получаем тип — класс Program, который находится в сборке MyApp.dll:
Type? t = asm.GetType(«Program»);
И в конце остается вызвать метод. Во-первых, получаем сам метод:
MethodInfo? square = t.GetMethod(«Square», BindingFlags.NonPublic | BindingFlags.Static);
Поскольку метод Square приватный и статический, то в качестве второго параметра в метод передаются флаги BindingFlags.NonPublic | BindingFlags.Static
И потом с помощью метода Invoke вызываем его:
object? result = square?.Invoke(null, new object[] < 7 >);
Здесь первый параметр представляет объект, для которого вызывается метод, а второй — набор параметров в виде массива object[]. Однако поскольку вызываемый метод — статический и не относится к какому-то определенному объекту, то первым аргументом в метод передается null.
Так как метод Square возвращает некоторое значение, то мы можем его получить из метода в виде объекта типа object.
Если бы метод не принимал параметров, то вместо массива объектов использовалось бы значение null : method.Invoke(null, null)
В сборке MyApp.exe в классе Program также есть и другой метод — метод Main, который также выполняет некоторую работу. Вызовем теперь его:
using System.Reflection; Assembly asm = Assembly.LoadFrom(«MyApp.dll»); Type? program = asm.GetType(«Program»); if (program is not null) < // получаем метод Main MethodInfo? main = program.GetMethod(«Main», BindingFlags.NonPublic | BindingFlags.Static); // вызываем метод Main main?.Invoke(null, new object[] < new string[] < >>); // Квадрат 5 равен 25 >
Так как метод Main является статическим и не публичным, то к нему также применяется битовая маска BindingFlags.NonPublic | BindingFlags.Static . И поскольку он в качестве параметра принимает массив строк, то при вызове метода передается соответствующее значение: main.Invoke(null, new object[]>)
Источник: metanit.com