Добавить dll в ресурсы
Ресурсы для создания библиотек DLL
Вот что нужно, чтобы создать библиотеку DLL:
- Редактор исходного кода.
- Компилятор для преобразования исходного кода в объектный, совместимый с оборудованием.
- Компоновщик для добавления кода из статических библиотек и создания исполняемого DLL-файла.
В современных интегрированных средах разработки (IDE), например Microsoft Visual Studio, есть все эти компоненты, а также смарт-редакторы, инструменты для отладки кода и управления несколькими проектами, мастера создания проектов и другие важные инструменты.
Вы можете создавать библиотеки DLL на нескольких языках, например C/C++, Pascal и Visual Basic. Так как исходный код API Excel — C и C++, в этой документации рассматриваются только эти два языка.
Преимущества библиотек DLL
Ниже приведены основные преимущества библиотек DLL.
С помощью DLL можно добавлять функции и команды в Microsoft Excel.
Создание DLL с ресурсами
Чтобы сделать DLL только с ресурсами, нужно создать и скомпилировать проект пустой DLL, которая содержит ссылки на файл ресурсов .RES, который содержит Ваши ресурсы.
Затем выполнить следующие шаги:
- Создайте RC файл, описывающий ресурсы, которые Вы хотите поместить в DLL. Как в примере: (adpdllresources - имя RC файла ASCII) - один ICON и один GIF добавлен в RC файл:
- Скомпилируйте RCфайл в RES файл при помощи компилятора ресурсов BRCC32
- Создайте проект пустой DLL. Сохраните его как adpResources.dpr - после компиляции DLL будет иметь имя adpResources.dll. Полный код проекта DLL будет иметь всего четыре строки в одном файле.
- Откомпилируйте Ваш DLL (убедитесь, что adpdllresources.res находится в том же каталоге, что и проект DLL
Как только DLL с ресурсами будет создан, Вы можете использовать его внутри Ваших приложений Delphi. Обратите внимание, что эти ресурсы внутри DLL может использовать любое приложение (не обязательно Delphi).
Динамическая загрузка
Динамическая загрузка горазда сложнее. Однако для динамической загрузки требуется только сама DLL ( не ненужен ни .lib ни заголовочный файл, хотя его можно исполбзовать для описания экспортируемых функций для предполагемого пользователя).
Давайте рассмотрим на примере, как производится динамическая загрузка. Создайте новый прокт DLL и внесите в него следующее:
Cкомпилируйте проект, в результате чего будет создана DLL.
Теперь создайте проект приложения анологичный проекту для использования статической загрузки (форма с кнопкой и обработчиком события кнопки OnClick) ниже приведен код приложения:(Unit11.cpp)
запустите это проект, при нажатии на кнопку должно выдаватся сообшение. Теперь разберемся, как это работает.
- void (__stdcall *Message)(char *s);-объявление указателя на функцию.
- HINSTANCE dllp = LoadLibrary("p.dll");- загрузка библиотеки в память.
- Message= (void(__stdcall *) (char*)) GetProcAddress(dllp, "_Message"); присвоение указателю адреса функции DLL.
- Message("Hi From Dinamic DLL"); рабочий вызов фунциий (собственно то для чего все это и делается).
- FreeLibrary(dllp);- выгрузка библиотеки из памяти.
Обратите внимание на то, что призагрузке можно указать точное местоположние библиотеки (необезательно в том же каталоге где и приложение).
Создание библиотеки DLL, содержащей только ресурсы
Чтобы создать библиотеку DLL, содержащую только ресурсы, создайте новый проект Windows DLL (не MFC) и добавьте в него свои ресурсы.
Выберите Проект Win32 в диалоговом окне Создание проекта. Введите имена проекта и решения, а затем нажмите кнопку ОК.
Создайте новый скрипт ресурсов, содержащий ресурсы для этой библиотеки DLL (такие как строка или меню). Сохраните файл .rc .
В меню Проект выберите Добавить существующий элемент, а затем вставьте в проект новый файл .rc .
Укажите параметр компоновщика /NOENTRY. Параметр /NOENTRY запрещает компоновщику привязывать ссылку на _main к библиотеке DLL, поэтому его необходимо указывать при создании библиотеки DLL, содержащей только ресурсы.
Построение библиотеки DLL.
В диалоговом окне Создание проекта выберите Мастер классических приложений Windows и нажмите кнопку Далее. На странице Настройка нового проекта введите имена проекта и решения, а затем нажмите кнопку Создать.
Создайте новый скрипт ресурсов, содержащий ресурсы для этой библиотеки DLL (такие как строка или меню). Сохраните файл .rc .
В меню Проект выберите Добавить существующий элемент, а затем вставьте в проект новый файл .rc .
Укажите параметр компоновщика /NOENTRY. Параметр /NOENTRY запрещает компоновщику привязывать ссылку на _main к библиотеке DLL, поэтому его необходимо указывать при создании библиотеки DLL, содержащей только ресурсы.
Построение библиотеки DLL.
Статическая загрузка
Создадим сперва проект (File / New / DLL). Будет создан проект, содержащий следующее:
и длинный коментарий предупреждающий вас о том, что для работо способности вашей DLL необходимо снеи обеспечить поствку некоторых dll если вы используете экземпляры класса String.
Для экспорта и импорта из DLL необходимо использовать моди фикаторы __export и __import соответсвенно. Но в C++ Builder можно использовать новое ключевое слово __delspec() с параметрами dllexport и dllimport соответсвенно. Сами понимаете, что для того чтобы эспортировать функции из библиотеки еужен один заголовочный файл с описаниями _delspec(dllexport) для экспортируемых функций, для импорта функций в приложение вам необходимо будет поставить анологичный заголовочный файл но с _delspec(dllimport) описаниями, что достаточно неудобно. Эта проблема решается легко: добавте в заголовочный файл библиотеки следующее:
Пример DLL: файл P.cpp
Не забудьте об объявлениях в начале файла. Зайдите в менеджер проектов.Там откройте свой проект и добавте .lib файл из предыдушего проект с DLL( правый клик, пункт ADD). Запустите проект.
Как видите, для того, чтобы вашу DLL можно было использовать необходимо три файла: сама DLL, заголовочный файл и библиотечный файл .lib.
С помощью DEF-файла
DEF-файл должен содержать следующие строки.
EXPORTS my_C_export = _my_C_export@8 my_Cpp_export
Ниже приведен общий синтаксис строки, следующей за оператором EXPORTS.
entryname[=internalname] [@ordinal[NONAME]] [DATA] [PRIVATE]
Обратите внимание, что функция C декорирована, но в DEF-файле компоновщику явно дано указание предоставлять эту функцию, используя имя из исходного кода (в данном примере). Компоновщик неявно экспортирует функцию C++, используя имя исходного кода, так что в DEF-файл необязательно включать расширенное имя.
Соглашение для вызовов функций API 32-разрядной Windows предусматривает следующее декорирование функций C: function_name становится function_name@ n, где n — количество байт, выраженное в виде десятичного числа, принимаемого всеми аргументами, при этом количество байт для каждого округляется до ближайшего числа, кратного четырем.
Размер всех указателей в Win32 — четыре байта. Тип возвращаемого значения не влияет на декорирование имени.
Чтобы компилятор C++ предоставлял функции, используя нерасширенные имена, заключите функцию и ее прототипы во внешний блок "C" , как показано в приведенном ниже примере. (Фигурные скобки <> здесь опущены, так как объявление относится только к блоку кода функции, расположенному непосредственно за ним.)
При размещении прототипов функции C в файлах заголовков, которые могут быть включены в исходные файлы C или C++, необходимо включить следующую директиву препроцессора.
Создание и использование только ресурсов в DLL
Кроме хранения ресурсов внутри .EXE файла, разработчик Delphi может также создать динамическую библиотеку, содержащую только ресурсы. Давайте посмотрим, как это сделать.
Ресурсы могут быть стандартные и определенные пользователем. Данные в стандартном ресурсе описывают иконку, курсор, меню, диалоговое окно, точечный рисунок, расширенный метафайл, шрифт, таблицу горячих клавиш, строки и версию. Определенный пользователем ресурс может содержать любые данные, требуемые приложением (другой .EXE, GIF, MP3 и т.д.).
Динамические библиотеки содержат общий код или ресурсы, которые могут использоваться многократными приложениями совместно.
Как использовать ресурсы из DLL
Чтобы использовать ресурсы из динамической библиотеки, просто загрузите DLL и ресурсы, которые Вы хотите использовать.
Следуйте этим шагам:
- Создайте новый проект Delphi. По умолчанию, Delphi добавляет одну форму к проекту. Сохраните проект
- Скопируйте DLL с ресурсами (adpResources.dll в папку, где Ваше новое приложение было сохранено
- Загрузите ресурс, как показано ниже.
Пример, как загрузить иконку factory и нарисовать ее на холсте Form1, когда Button1: TButton была нажата).
Если Вы добавите поддержку GIF, Вы можете использовать изображение GIF, хранимое в ресурсном DLL, а также его рисовать:
Здравствуйте. Не хочу делать инсталятор программы, т.к. у программы есть всего 1 зависимый dll файл.
Хочу добавить этот dll в ресурсы, а при первом запуске просто выгружать его в папку с программой.
В Visual Studio делаю так:
1. Правой клавишей по папке "Resources" -> Добавить -> Существующий элемент -> keyboard.dll
Мой файл виден в списке (папке) Resources, но обратиться к нему программно не получается.. Его просто нет..
Сохранять хотел так..
File.WriteAllBytes("keyboard.dll", BotMek.Properties.Resources. keyboard.dll ); //Не видит keyboard.dll
Добавить dll в ресурсы
Хочу добавить dll в ресурсы экзешника и при запуске "распаковывать" dll в отдельный файл. .
Как добавить в папку с программой java .exe?
Здраствуйте)) я написала одну програмку на Java в Netbeans и должна добавить в папку .exe т.к .
Не выйдет, dll не получается добавить как ссылку (именно эту dll не получается)
Прикрепляю файл dll, попробуйте сами.
Я уже смотрел этот пример (и другие похожие) и ничего не вышло.
Мой файл виден в списке (папке) Resources, но обратиться к нему программно не получается.. Его просто нет..
Помню, честное слово минут 60 пытался разобраться, потом плюнул, уж слишком много нового придется учить, т.е. на скорую руку это не сделать, лишь в долгосрочной перспективе.
Первое, что я не понял это как получать нужный байт код.
Второе это как его использовать, в общем то я вообще ничего не понял.
P.s. На пример 2 натыкался в сети, будет больше времени, буду разбираться
При чем тут байткод, это обычный x86-ассемблер. Там даже комментарии написаны, какой байт что означает.
Добавлено через 53 секунды
2 пример это то же самое, только классы сгруппированы и добавлен вариант 32-битного ассемблера.
Добавлено через 6 минут
Nalik, ассемблер можно скомпилить любой тулзой, например этой. Вбиваем туда например
lFreeManl, не знаю, что имеется ввиду. Тут просто 2 этапа:
1. Пишем асм (для этого нужно его знать, это да)
2. Копипастим код выше и выполняем.
Со вторым думаю проблем нет, с первым - тут от шарпа ничего не зависит
Здравствуйте. Не хочу делать инсталятор программы, т.к. у программы есть всего 1 зависимый dll файл.
Хочу добавить этот dll в ресурсы, а при первом запуске просто выгружать его в папку с программой.
Пример моей,возможно не правильной по всем параметрам, но рабочей, реализации
Нужно добавить в ресурсы используемую dll/в моем случае Ionic.Zip.dll
И да,в настройках приложения выбрать Program2 в качестве точки входа.
Как вариант, файл можно загнать в моссив байт и хранить в переменной, из которой обратно потом и создавать.
Не освобождает ресурсы(набор оперативной памяти программой)
Есть программа, которая должна делать скриншоты каждую минуту, посмотрел в диспетчере, стал кушать.
Как сохранить форму в dll и потом вызвать её из проэкта к которому подключена эта dll?
Как сохранить форму в dll и потом вызвать её из проэкта к которому подключена эта dll?
Создать свою папку под ресурсы
У мен под проект идет очень много изображений и есть очень остра необходимость как-то.
Как менять картинки в PictureBox и внести папку с фотографиями в ресурсы?
Всем привет! Недавно столкнулся с проблемой, что я хотел добавить папку с фото в ресурсы проекта.
Запись файла в папку с программой по умолчанию
Как правильно указать папку программы для записи в эту папку текстового файла? Есть такой код.
Как сохранить картинку в папку с программой?
В папке с программой имеется папка Фото.Как по нажатию кнопки сохранить туда картинку открытую в.
В библиотеке DLL, содержащей только ресурсы, нет ничего, кроме ресурсов, таких как значки, растровые изображения, строки и диалоговые окна. Библиотеки DLL, содержащие только ресурсы, удобно использовать, когда необходимо предоставить нескольким программам общий доступ к одному и тому же набору ресурсов. С их помощью можно также легко предоставлять приложение с ресурсами, локализованными для нескольких языков. Дополнительные сведения см. в разделе Локализованные ресурсы в приложениях MFC: вспомогательные библиотеки DLL.
Использование библиотеки DLL, содержащей только ресурсы
Приложение, которое использует библиотеку DLL, содержащую только ресурсы, должно вызывать LoadLibraryEx или связанную функцию, чтобы явно привязать эту библиотеку DLL. Для доступа к ресурсам следует вызывать универсальные функции FindResource и LoadResource , которые работают с ресурсами любого типа. Для доступа к конкретному ресурсу можно также использовать вызов одной из следующих функций:
Библиотека — это скомпилированный код, который обеспечивает функции исполняемого приложения и предоставляет ему данные. Библиотеки могут быть связаны статически и динамически, обычно у них расширение LIB и DLL соответственно. Статические библиотеки (например, библиотека времени выполнения C) связываются с приложением во время компиляции и становятся частью полученного исполняемого файла. Приложение загружает библиотеку DLL, когда она необходима (обычно при запуске). Одна библиотека DLL может загружать другую библиотеку DLL и динамически ссылаться на нее.
Экспорт функций и команд
При компиляции проекта DLL компилятор и компоновщик должны знать, какие функции экспортировать, чтобы предоставить к ним доступ в приложении. В этом разделе описаны возможные способы.
При компиляции исходного кода компиляторы обычно изменяют имена функций. Для этого они обычно добавляют символы в начало или конец имени. Этот процесс называется декорирование имени. Необходимо убедиться, что приложение, загружающее библиотеку DLL, может распознать имя экспортируемой функции. Для этого может потребоваться дать указание компоновщику сопоставить расширенное имя с более простым именем экспорта. Это может быть имя из исходного кода или другое.
Способ декорирования имени зависит от языка и способа вызова функции, задаваемого компилятором, т. е. соглашения о вызовах. Стандартное межпроцессное соглашение о вызовах для Windows, используемое в библиотеках DLL, — это WinAPI. В файлах заголовков Windows оно обозначено как WINAPI с помощью декларатора Win32 __stdcall.
Функция, экспортируемая в DLL-файл для Excel (функция листа, функция, эквивалентная листу макросов, или пользовательская команда) всегда должна использовать соглашение о вызовах WINAPI / __stdcall. В определение функции необходимо явно включить указатель WINAPI, так как по умолчанию в компиляторах Win32 используется соглашение о вызовах __cdecl, также обозначенное как WINAPIV.
Вы можете сообщить компоновщику о необходимости экспорта функции, а также ее внешнее имя несколькими способами:
В проекте можно использовать все три способа, они поддерживаются и компилятором, и компоновщиком, но не следует экспортировать одну функцию более чем одним способом. Например, предположим, что библиотека DLL содержит два модуля исходного кода, C и C++, которые содержат две функции для экспорта — my_C_export и my_Cpp_export соответственно. Для простоты предположим, что функции принимают один числовой аргумент двойной точности и возвращают данные того же типа. В следующих разделах описываются варианты экспорта функций с помощью каждого из этих методов.
С помощью декларатора __declspec(dllexport)
Ключевое слово __declspec(dllexport) можно использовать в объявлении функции указанным ниже образом.
Ключевое слово __declspec(dllexport) необходимо добавить в крайней левой части объявления. Преимущества этого подхода: функцию не нужно указывать в DEF-файле, а состояние экспорта указывается вместе с определением.
Если вы не хотите декорировать имя функции C++, необходимо объявить функцию следующим образом.
Компоновщик сделает функцию доступной под именем my_undecorated_Cpp_export, то есть именем из исходного кода, без декорирования.
Например, при использовании Microsoft Visual Studio эти строки можно включить в общий файл заголовка, как показано ниже.
Если такой заголовок включен в исходные файлы, две функции, приведенные в качестве примера, можно экспортировать следующим образом.
Обратите внимание, что директиву необходимо поместить в код функции. Ее можно развернуть, только если параметры /EP и /P компилятора не заданы. При использовании этого способа исчезает необходимость в DEF-файле и объявлении __declspec(dllexport), а спецификация состояния экспорта указывается в коде функции.
Сейчас мы рассмотрим для чего нужны DLL (Dynamic Link Library - динамически компануемая библиотека) и как их создавать. DLL- это участок кода хранимый в файле с расширением .dll. Код может быть использован другими программами, но сама посебе библиотека прораммой не является. Вобщем-то, динамически компонуемые библиотеки представляют собой набао скомпилированныых функций. Но у ютих библиотек есть свой особенности, так например, если каккието две или более программы для Windows одновременно исполняются и используют функции, находящиеся в одной DLL, то в памяти будет постоянно находится только одна библиотека, обеспечивая тем самым экономное расходование памяти. Загрузка библиотеки в память может быть статической и динамической.
При статической загрузке DLL автоматически загружается при запуске исользующего ее приложения. Такая DLL содержит экспортируемые функции, описание которых находится в файле библиотеки импорта(import library file - .lib). Для использования статической загрузки вы должны на этапе компоновки к программе додключить .lib файл вашей DLL. В C++ Builder это сводится к включения в проект .lib файла через менджер проектов.
При диамической загрузке вы можете загружать DLL при необходимости, выгрузить ее когода она ненужна. Однако работать с такими библиотеками сложнее чем со статическими. Рассмотрим созздание и использование DLL статической загрузки.
Читайте также: