Почему необходимо переносить часть кода в библиотеки отдельных проектов, скомпилированных в dll-файлы

Обновлено: 07.07.2024

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

Создание управляемого подключаемого модуля

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

  • Если библиотека DLL содержит код API Unity, перед компиляцией необходимо сделать собственные библиотеки DLL Unity доступными для компилятора:
    1. Чтобы найти библиотеки DLL Unity:
      • В Windows перейдите по адресу: C:\Program Files\Unity\Hub\Editor\\Editor\Data\Managed\UnityEngine
      • В macOS:
        1. Найдите файл Unity.app на своем компьютере. Путь к DLL Unity в macOS: /Applications/Unity/Hub/Editor/ /Unity.app/Contents/Managed/UnityEngine
        2. Нажмите правой кнопкой мыши на Unity.app
        3. Выберите Показать содержимое пакета.

      Если библиотека DLL не содержит кода API Unity или вы уже сделали библиотеки DLL Unity доступными, следуйте документации вашего компилятора, чтобы скомпилировать файл .dll. Конкретные параметры, которые вы используете для компиляции DLL, зависят от вашего компилятора. использовать. Например, командная строка для компилятора Roslyn csc может выглядеть в macOS следующим образом:

      csc /r:/Applications/Unity/Hub/Editor/ /Unity.app/Contents/Managed/UnityEngine.dll /target:library /out:MyManagedAssembly.dll /recurse:*.cs

      В этом примере:

      • Используйте параметр /r, чтобы указать путь к библиотеке для включения в сборку, в данном случае к библиотеке UnityEngine.
      • Используйте параметр /target, чтобы указать тип требуемой сборки; «библиотека» означает сборку DLL.
      • Используйте /out, чтобы указать имя библиотеки, в данном случае — «MyManagedAssembly.dll».
      • Добавьте имена исходных файлов, которые необходимо включить. Используйте метод /recurse, чтобы добавить все файлы, оканчивающиеся на «.cs», в ваш текущий рабочий каталог и любые подпапки. Полученный файл .dll появится в той же папке, что и исходные файлы.

      Использование управляемого подключаемого модуля

      После того как вы скомпилировали DLL, вы можете перетащить файл .dll в проект Unity, как и любой другой ресурс. Затем вы можете:

      • Разверните управляемый подключаемый модуль, чтобы просмотреть отдельные классы внутри библиотеки.
      • Перетащите классы, производные от MonoBehaviour, в игровые объекты.
      • Используйте классы, отличные от MonoBehaviour, напрямую из других скриптов.

      Создание библиотеки DLL с помощью Visual Studio

      В этом разделе объясняется:

      • Как создать простой пример библиотеки DLL и интегрировать его в Visual Studio
      • Как подготовить сеанс отладки для библиотеки DLL в Unity.

      Настройка проекта

      Написание кода DLL

      1. Для этого примера переименуйте класс по умолчанию в MyUtilities в обозревателе решений.
      2. Замените его код следующим:
        1. Создайте проект для создания файла DLL вместе с его отладочными символами.

        Отладка библиотеки DLL в Unity

        Чтобы настроить сеанс отладки для DLL в Unity:

          Создайте новый проект в Unity и скопируйте созданный файл .dll (например,

        Unity отображает вывод кода из DLL в окне консоли

        Вы можете использовать небезопасный код для:

        • Доступ к памяти с помощью указателей.
        • Выделить необработанную память.
        • Вызывать методы с помощью указателей.

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

        Я понимаю, что разделение кода на несколько частей, каждая из которых компилируется в отдельную DLL, хорошо с точки зрения разработчика. Это означает, что:

        • Если разработчик изменяет один проект, ему приходится перекомпилировать только этот и зависимые, что может быть намного быстрее.
        • Проект может выполняться одним разработчиком в команде, в то время как другие разработчики будут просто использовать предоставленные интерфейсы, не вникая в код.
        • Автоматическое обновление программного обеспечения иногда может выполняться быстрее и с меньшей нагрузкой на сервер.

        А как насчет конечного пользователя? Разве не плохо поставлять программу, состоящую из одного EXE и нескольких DLL, когда все можно сгруппировать? Ведь:

        • Пользователь может даже не понимать, что это за файлы и почему они заполняют память на его жестком диске,
        • Пользователь может захотеть переместить программу, например, сохранить ее на USB-накопителе. Наличие одного большого исполняемого файла упрощает задачу,
        • Большинство антивирусных программ проверяют каждую DLL. Проверка одного исполняемого файла будет намного быстрее, чем проверка исполняемого файла меньшего размера и десятков библиотек.
        • Использование DLL замедляет некоторые процессы (например, в .NET Framework необходимо найти "хорошую" библиотеку и проверить, подписана ли она),
        • Что произойдет, если DLL будет удалена или заменена неверной версией? Каждая ли программа справляется с этим? Или он вылетает, даже не объясняя, что с ним не так?
        • У наличия одного большого исполняемого файла есть и другие преимущества.

        Не лучше ли, с точки зрения конечных пользователей, для программ малого/среднего размера поставлять один большой исполняемый файл? Если да, то почему нет инструментов, позволяющих это сделать легко (например, волшебного инструмента, интегрированного в распространенные IDE, который компилирует все решение в один исполняемый файл, конечно, не каждый раз, а по требованию или во время развертывания).

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

        6 ответов 6

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

        Еще несколько причин использования DLL

        Некоторые библиотеки плохо работают вместе в одной сборке, но их можно настроить так, чтобы они вели себя в DLL (например, одна DLL может использовать WTL3, а другая требует WTL8).

        Некоторые библиотеки DLL могут содержать компоненты для загрузки в другие исполняемые файлы (глобальные перехватчики, расширения оболочки, надстройки браузера).

        Некоторые библиотеки DLL могут быть сторонними и доступны только в виде DLL.

        В компании может быть повторное использование — даже если вы видите только один «общедоступный» продукт, он может использоваться в дюжине внутренних проектов с использованием этой библиотеки DLL.

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

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

        Влияние времени сборки
        Возможно, вы недооцениваете влияние времени сборки и поддержания стабильной сборки для крупных проектов. Если сборка занимает даже 5 минут, вы можете эфемистически назвать это «заставить разработчиков думать наперед, а не возиться, пока не покажется, что все работает нормально». Но это серьезно отнимает время и сильно отвлекает.

        Сложно сократить время сборки одного проекта. Работая на VC9, распараллеливание сборки в рамках одного проекта шатко, как и инкрементный компоновщик. Время соединения особенно трудно «оптимизировать» на более быстрых машинах.

        Независимость от разработчиков
        Еще одна вещь, которую вы можете недооценивать.
        Чтобы использовать DLL, вам нужны .dll и .h. Чтобы скомпилировать и скомпоновать исходный код, вам обычно нужно настроить включаемые каталоги, выходные каталоги, устанавливать сторонние библиотеки и т. д. На самом деле это проблематично.

        В Windows библиотека динамической компоновки (DLL) представляет собой разновидность исполняемого файла, который действует как общая библиотека функций и ресурсов. Динамическое связывание — это возможность операционной системы. Он позволяет исполняемому файлу вызывать функции или использовать ресурсы, хранящиеся в отдельном файле. Эти функции и ресурсы можно скомпилировать и развернуть отдельно от исполняемых файлов, которые их используют.

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

        Различия между динамической и статической ссылками

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

        Различия между приложениями и библиотеками DLL

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

        Приложение может иметь несколько экземпляров, работающих в системе одновременно. DLL может иметь только один экземпляр.

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

        Преимущества использования библиотек DLL

        Динамическая привязка к коду и ресурсам имеет ряд преимуществ по сравнению со статической привязкой:

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

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

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

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

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

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

        Динамическое связывание предоставляет механизм расширения классов библиотеки Microsoft Foundation Class library (MFC). Вы можете получить классы из существующих классов MFC и поместить их в библиотеку DLL расширения MFC для использования приложениями MFC.

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

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

        Подробнее о том, как создавать и использовать библиотеки DLL

        В следующих статьях содержится подробная информация о том, как создавать библиотеки DLL C/C++ в Visual Studio.

        Пошаговое руководство. Создание и использование библиотеки динамической компоновки (C++)
        Описывает создание и использование библиотеки DLL с помощью Visual Studio.

        Виды библиотек DLL
        Информация о различных типах библиотек DLL, которые можно создать.

        Часто задаваемые вопросы о библиотеках DLL
        Содержит ответы на часто задаваемые вопросы о библиотеках DLL.

        Связать исполняемый файл с библиотекой DLL
        Описывает явное и неявное связывание с библиотекой DLL.

        Инициализировать DLL
        Обсуждается код инициализации DLL, который должен выполняться при загрузке DLL.

        Поведение DLL и библиотеки времени выполнения Visual C++
        Описывает последовательность запуска DLL библиотеки времени выполнения.

        LoadLibrary и AfxLoadLibrary
        Обсуждается использование LoadLibrary и AfxLoadLibrary для явного связывания с библиотекой DLL во время выполнения.

        GetProcAddress
        Обсуждается использование GetProcAddress для получения адреса экспортируемой функции в DLL.

        FreeLibrary и AfxFreeLibrary
        Обсуждается использование FreeLibrary и AfxFreeLibrary, когда модуль DLL больше не нужен.

        Порядок поиска библиотеки Dynamic-Link
        Описывает путь поиска, который операционная система Windows использует для поиска библиотеки DLL в системе.

        Состояния модуля обычной библиотеки DLL MFC, динамически связанной с MFC.
        Описывает состояния модуля обычной библиотеки DLL MFC, динамически связанной с MFC.

        Библиотеки расширения MFC
        Описывает библиотеки DLL, которые обычно реализуют повторно используемые классы, производные от существующих классов MFC.

        Создание библиотеки DLL только для ресурсов
        Обсуждается библиотека DLL только для ресурсов, которая не содержит ничего, кроме ресурсов, таких как значки, растровые изображения, строки и диалоговые окна.

        Локализованные ресурсы в приложениях MFC: вспомогательные библиотеки DLL
        Обеспечивает расширенную поддержку вспомогательных библиотек DLL, которая помогает создавать приложения, локализованные для нескольких языков.

        Импорт и экспорт
        Описывает импорт общедоступных символов в приложение или экспорт функций из DLL

        Активная технология и библиотеки DLL
        Позволяет реализовать объектные серверы внутри библиотеки DLL.

        Автоматизация в DLL
        Описывает, что предоставляет параметр автоматизации в мастере DLL MFC.

        Соглашения об именах для библиотек DLL MFC
        Обсуждается, как библиотеки DLL и библиотеки, включенные в MFC, следуют структурированному соглашению об именах.

        Вызов функций DLL из приложений Visual Basic
        Описывает, как вызывать функции DLL из приложений Visual Basic.

        Связанные разделы

        Использование MFC как части библиотеки DLL
        Описывает обычные библиотеки DLL MFC, которые позволяют использовать библиотеку MFC как часть библиотеки динамической компоновки Windows.

        Повторное использование кода при разумном применении сокращает время выхода на рынок и повышает общее качество продукта. Однако решение о том, от каких компонентов вы зависите и как их интегрировать, может оказать огромное влияние на скорость разработки.

        Проект был представлен файлом .csproj, но зависимости (включая ссылки на пакеты NuGet) хранились отдельно в файле packages.config. Здесь вы можете получить сторонние библиотеки из центральной общедоступной коллекции NuGet и перенести свой проект на другой компьютер, не копируя библиотеки — просто скопируйте файл packages.config и выполните восстановление пакета.

        Начиная с Visual Studio 2017, проект представлен файлом .csproj с зависимостями (ссылками на пакеты NuGet), перечисленными в разделе PackageReference этого файла. Для некоторых типов проектов зависимости по-прежнему хранятся в этом отдельном файле packages.config.

        Спасибо, что предоставили подробности. Ваш адрес электронной почты добавлен в наш список подписки.

        Файл .csproj

        Файл проекта обычно включает:

        • Список файлов, включенных в проект
        • Зависимости:
          • Другие проекты из того же .sln
          • Клиентские библиотеки и другие сборки платформы
          • Системные сборки
          • Сторонние библиотеки (пакеты NuGet) — PackageReference

          Взаимодействия с файлами .csproj

          Файл .csproj можно редактировать напрямую, хотя это несколько рискованно (если у вас нет достаточного опыта), поскольку это может привести к повреждению файла XML, что может нарушить согласованность вашего проекта.

          Как использовать файл .csproj

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

          Если при создании нового проекта в Visual Studio вы не найдете нужный шаблон, вам может потребоваться установить дополнительные рабочие нагрузки. Это можно сделать, нажав "Установить дополнительные инструменты и компоненты", выбрав рабочие нагрузки для установки и нажав "Изменить".

          Файл .sln

          Для сборки чего-либо в Visual Studio требуется решение, и это решение должно содержать как минимум один проект, по одному для каждого созданного вывода сборки. Решения — это XML-файлы (.sln), действующие как контейнеры, которые Visual Studio использует для организации одного или нескольких связанных проектов.

          Взаимодействия с файлами .sln

          При добавлении/удалении проектов в Visual Studio изменения записываются в файл .sln.

          При открытии решения Visual Studio автоматически загружает все содержащиеся в нем проекты.

          Как использовать файл .sln

          Если в вашей кодовой базе много проектов, вы можете использовать несколько файлов .sln, чтобы минимизировать объем и ускорить этапы разработки. Например, у вас может быть:

          • Одно решение только для основных функций: база данных, API, веб-приложение
          • Одно решение, которое также включает библиотеки интеграции, связанные с некоторыми основными функциями интеграции, которые не изменяются слишком часто
          • Одно решение для всех проектов

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

          Файл packages.config

          Packages.config — это XML-файл, используемый в некоторых типах проектов для хранения списка зависимостей пакетов. Для большинства типов проектов он заменяется PackageReference. Пример:


          Взаимодействия Packages.config

          При добавлении/удалении/обновлении ссылок на пакеты NuGet (с помощью пользовательского интерфейса диспетчера пакетов Visual Studio NuGet, интерфейса командной строки dotnet или интерфейса командной строки nuget.exe) эти изменения будут отражены в файле packages.config.

          Visual Studio и NuGet используют файл packages.config в качестве ссылки при выполнении операции восстановления.

          Как использовать файл packages.config

          В NuGet 2 вам нужно будет зафиксировать каждый отдельный пакет, чтобы включить его. В NuGet 4 (VS 2017) необходимо указывать только зависимости верхнего уровня.

          Если вы хотите перенести проект на другой компьютер (например, на сервер сборки), вам не нужно копировать пакеты. Вы можете просто скопировать файлы проекта, включая packages.config, и выполнить операцию восстановления NuGet на целевом компьютере.

          Ссылка на пакет


          Ранее эти ссылки хранились в отдельном файле с именем project.json. Еще раньше они хранились в файле packages.config, который фактически до сих пор используется для некоторых типов проектов.

          Взаимодействия со ссылками на пакеты

          При добавлении, удалении или обновлении ссылок на пакеты NuGet (с помощью пользовательского интерфейса диспетчера пакетов Visual Studio NuGet, интерфейса командной строки dotnet или интерфейса командной строки nuget.exe) эти изменения будут отражены в разделе PackageReferences.

          Операция восстановления пакета устанавливает все зависимости проекта и опирается на содержимое PackageReference как на основу. Восстановление пакета можно запустить несколькими способами:

          Как использовать PackageReference

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

          Файл project.json

          Файл содержит следующие основные разделы:

          Взаимодействия с файлом project.json

          Как использовать файл project.json

          Этот файл устарел, вместо него используются файлы .csproj и PackagesReference или packages.config. Поэтому, если возможно, не используйте его или откажитесь от него.

          В проектах, использующих файл project.json, при выполнении операции восстановления пакета создается файл project.lock.json. Он включает версию, содержимое и зависимости всех пакетов в вашем проекте в виде моментального снимка.

          Файл nuget.config

          Например, в разделе packageManagement задан формат управления пакетами по умолчанию: 1 — для PackageReference, а 0 — для packages.config.


          Файл .nuspec

          .nuspec – это XML-файл, который функционирует как манифест, содержащий метаданные пакета.

          Он включен в каждый пакет NuGet и используется как для сборки пакета, так и в качестве источника информации для потребителей пакета.

          Microsoft рекомендует следующие подходы для создателей пакетов:

          • Для проектов, отличных от SDK, которые используют packages.config: используйте .nuspec с командой пакета nuget.exe.
          • Для проектов в стиле SDK: файл .nuspec не требуется, и вы можете использовать целевые команды dotnet.exe pack или msbuild pack.
          • Для проектов, перенесенных из packages.config в PackageReference: файл .nuspec не требуется для создания пакета. Следует использовать команду msbuild -t:pack.

          Заключение

          Об авторе

          Читайте также: