Michael Haephrati Ответов: 2

Встраивание значка в статическую библиотеку


Есть ли способ встроить ресурсы (например, значки, диалоги) в статическую библиотеку c++ (Win32 API)?
Моя цель состоит в том, чтобы встроить значок в статическую библиотеку таким образом, чтобы функции, использующие LoadIcon, работали так, как если бы это был обычный файл .exe, поэтому основное приложение может ссылаться только на статическую библиотеку и включать заголовочный файл, не требуя добавления других файлов, таких как файлы .rc, файлы .ico и т. д.
Очевидно, что основное приложение, использующее статическую библиотеку, не имеет этого ресурса, поэтому LoadIcon потерпит неудачу, однако мне было интересно, есть ли обходной путь, чтобы заставить его работать. Статический массив с данными значка может работать до тех пор, пока будут работать стандартные вызовы API (такие как LoadIcon).

Что я уже пробовал:

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

2 Ответов

Рейтинг:
2

Jochen Arndt

Вы могли бы взглянуть на эту так называемую нить:
visual c++ - ресурсы VC++ в статической библиотеке - переполнение стека[^].

Особенно интересно выглядит второе решение (до сих пор я такого никогда не делал). Это решение также ссылается на Связывание ресурсов из статической библиотеки | Tech Leaves[^].


Michael Haephrati

Я читал их, но мы хотим развернуть 2 файла: .lib и .h. эти решения требуют развертывания файла .rc и наличия того, кто использует нашу статическую библиотеку, чтобы связать / включить ее.

Jochen Arndt

Тогда, с моей точки зрения, нет никакого решения.
Так резьба покрывает все это.

Если вы строго ограничены lib и заголовочным файлом, вы должны хранить данные в виде двоичных массивов и предоставлять вспомогательные функции для загрузки их как ресурсов, как указано в потоке.

Если вы можете принять третий файл, я бы поместил ресурсы в библиотеку DLL. На это можно ссылаться с помощью
#pragma comment(lib, ...)
в пределах статической библиотеки.
Статическая библиотека также может загружать DLL и предоставлять функцию для возврата дескриптора модуля.

Michael Haephrati

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

Рейтинг:
16

Michael Haephrati

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

1. Значок преобразуется в статический массив типа byte. bin2c можно использовать и для этого.

2. данные преобразуются в дескриптор HICON. Вот как я это сделал:

HICON GetIcon()
{ 
   DWORD dwTmp;
   int offset;
   HANDLE hFile;
   HICON hIcon = NULL;
   offset = LookupIconIdFromDirectoryEx(s_byIconData, TRUE, 0, 0, LR_DEFAULTCOLOR);
   if (offset != 0)
   {
      hIcon = CreateIconFromResourceEx(s_byIconData + offset, 0, TRUE, 0x00030000, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
   }
   return hIcon;  
}


3. GetIcon используется вместо LoadIcon.
Вместо вызова:

m_hIcon = ::LoadIcon(hInstanceIcon, MAKEINTRESOURCE(pXMB->nIcon));

Я звоню
m_hIcon = GetIcon()


Чтобы проверить это, я создал консольное приложение и новую статическую библиотеку. Я добавил в статическую библиотеку следующее: XMessageBox - реверс-инженерии сообщение()[^] класс, который позволяет использовать пользовательский значок.
Консольное приложение просто вызывает функцию, расположенную в статической библиотеке, и отображается значок!

Смотреть также: Как встроить ресурсы в статическую библиотеку[^]