Перейти к содержанию

C++ Статическая библиотека .lib с собственными ресурсами


Antonshka

Рекомендуемые сообщения

Приветствую, никто не сталкивался с такой задачей?

Например, есть статическая библиотека, .lib файл, в его ресурсах есть курсор, этот курсор используется некоторым классом этой самой библиотеки.

Если попытаться подключить эту библиотеку к иному какому проекту, то курсор уже не определяется.

 

Как стало известно из интернета, курсор не определяется потом что .lib файл не имеет собственного HINSTANCE. И когда программа пытается отыскать ресурс курсора, она ищет его в своих собственных ресурсах, а не в тех что от .lib файла.

 

Один человек решил эту проблему переводом иконки в байт код вида 0x0. Затем добавлением его в .lib файл в виде Byte[] arrayOfIcon = { 0X02, 0X0F, ... }. Затем вызовом winapi функций LookupIconIdFromDirectoryEx и CreateIconFromResourceEx. Мудренный способ конечно. Вот его описание

 

Может есть попроще способ?

Ссылка на комментарий
Поделиться на другие сайты

Почему DLL может содержать в себе ресурсы, а LIB не может. Если у них основная разница в том что одна линкуется динамически, а другая ститически?

Ссылка на комментарий
Поделиться на другие сайты

9 часов назад, imaginary сказал:

В DLL по твоему ресурсы содержатся не таким образом?

Точно не знаю, но предполагаю что в обычном виде. Без 0x. Просто, - ec d3 e5 ec d8 ea (это я открыл файл .res в HEX Editor).

А тот человек по сути просто создавал переменную, массив. Вида 0xec, 0xd3, 0xe5, 0xec, 0xd8, 0xea.

Ссылка на комментарий
Поделиться на другие сайты

Объясните пожалуйста, DLL хранится в оперативной памяти  в одном экземпляре

Спойлер

Dynamic linking saves memory and reduces swapping. Many processes can use a DLL simultaneously, sharing a single copy of the read-only parts of a DLL in memory.

Advantages of using DLLs

 

То есть каждое приложение использующее DLL имеет в своем адресном пространстве только переменные из этой DLL, но не сами функции?

Тогда в чьем адресном пространстве находится сами функции?

Если я изменю функцию например для memcpy, то получается что все приложения будут использовать модифицированную версию?

Никак не пойму.

Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, imaginary сказал:

0xEC и EC Это одно и тоже, просто 0x это указание что бы воспринималось как hex

Я понял про что ты говоришь. Я имел ввиду что это неудобно, переводить файл в байты, и писать их в массив. Думал есть что-нибудь попроще.

Но оказалось что нет. Статическая библиотека это просто архив кода. В конечный .lib файл не входят его ресурсы. Вот DLL да, она их может содержать. После создания .lib файла, в папке Release или Debug будет лежать файл ресурсов с расширением .res. Его можно подключить после к проекту, который будет использовать библиотеку, но это не то что мне хотелось.

Так что вот, либо переводить в байты, либо включать .res файл, либо никак.

Ссылка на комментарий
Поделиться на другие сайты

1 час назад, Antonshka сказал:

Я имел ввиду что это неудобно, переводить файл в байты, и писать их в массив

Пишешь обычную утилитку или находишь на просторах интернетов утилитку bin2hex. Она тебе сразу массивчик сделает. Утилита пишется за пять минут на коленке на любом языке (и тем более на плюсах)

 

 

Ссылка на комментарий
Поделиться на другие сайты

15 минут назад, Xipho сказал:

Пишешь обычную утилитку или находишь на просторах интернетов утилитку bin2hex. Она тебе сразу массивчик сделает. Утилита пишется за пять минут на коленке на любом языке (и тем более на плюсах)

Это да, но я надеялся не таким способом. Не способом перевода байт в вид 0x0. А затем ручным внесением его в файл в виде определения массива.

Ссылка на комментарий
Поделиться на другие сайты

Как можно указать для EXE приложения путь к поиску DLL, которая прилинкована статически, через .lib файл, и которая расположена не в корневом каталоге этого приложения?

Например EXE расположен в "D/:Tool/Run.exe". А DLL в "D/:Tool/Pack/Math.dll".

MSDN - Search Order for Desktop Applications - согласно написанному, можно использовать DLL redirection, но при таком способе нужно создать в реестре ключ, и перезапустить компьютер. Это не подходит.

Через manifest, но я не нашел примеров.

 

Ссылка на комментарий
Поделиться на другие сайты

39 минут назад, Antonshka сказал:

Как можно указать для EXE приложения путь к поиску DLL

У винмейна один из параметров - командная строка. При желании можно взять и разобрать ее на составляющие, и выдернуть местонахождение программы

Ссылка на комментарий
Поделиться на другие сайты

42 минуты назад, Xipho сказал:

У винмейна один из параметров - командная строка. При желании можно взять и разобрать ее на составляющие, и выдернуть местонахождение программы

Это для параметра функции LoadLibary? Но мне нужно не для нее.

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

Согласно MSDN есть всего два способа перенаправления. DLL redirection и side-by-side components.

DLL redirection не подходит. Остается side-by-side, он же манифест. Но манифест вещь непростая, с его XML.

Буду читать далее про него.

Ссылка на комментарий
Поделиться на другие сайты

Ничего более для меня подходящего как кроме определения байт курсора в виде массива в .cpp файле я не нашел.

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

Если использовать редактор курсора Microsoft Visual Studio, и создать свой самодельный курсор, - нарисовать, установить HotSpot, сохранить в файл, перевести в байты, определить в .cpp, то тогда нужно использовать функции

Спойлер
/*
Файл курсора - Test.cur (создан через Microsoft Visual Studio).
*/

unsigned char cursorsData[4362] = {0x52, 0x49, 0x46, 0x46, 0x02, 0x11, 0x00, 0x00, ... };
int offset = LookupIconIdFromDirectoryEx(cursorsData, FALSE, 0, 0, LR_DEFAULTCOLOR);
HCURSOR cursor = static_cast<HCURSOR>(CreateIconFromResourceEx(cursorsData + offset, 4362, TRUE, 0x00030000, 32, 32, LR_DEFAULTCOLOR | LR_DEFAULTSIZE));
                                      
/*
Для функции CreateIconFromResourceEx здесь третий параметр TRUE, хотя должен быть FALSE, так как согласно MSDN - 
"Indicates whether an icon or a cursor is to be created. If this parameter is TRUE, an icon is to be created. If it is FALSE, a cursor is to be created."
Но с FALSE не работает.
*/
                                      
/*
Если не использовать функцию LookupIconIdFromDirectoryEx, созданный нами курсор не появится.
Также, если курсор был создан через Microsoft Visual Studio, как в текущем случае, то HotSpot для него не определится. А значит, этот вариант, с курсорами из Microsoft Visual Studio, - не подходит.
*/

 

 

Если использовать редактор курсора, например я пробовал "RealWorld Cursor Editor", то для курсора формата .cur, нужно использовать

Спойлер
/*
Файл курсора - Test.cur (создан через RealWorld Cursor Editor).
*/

unsigned char cursorsData[4362] = {0x52, 0x49, 0x46, 0x46, 0x02, 0x11, 0x00, 0x00, ... };
HCURSOR cursor = static_cast<HCURSOR>(CreateIconFromResourceEx(cursorsData, 4362, TRUE, 0x00030000, 32, 32, LR_DEFAULTCOLOR | LR_DEFAULTSIZE));
                                      
/*
Для функции CreateIconFromResourceEx здесь третий параметр TRUE, хотя должен быть FALSE, так как согласно MSDN - 
"Indicates whether an icon or a cursor is to be created. If this parameter is TRUE, an icon is to be created. If it is FALSE, a cursor is to be created."
Но с FALSE не работает.
*/
                                      
/*
HotSpot определяется нормально. А значит, этот вариант, с курсорами из RealWorld Cursor Editor, - подходит.
*/

 

 

Если использовать редактор курсора, например я пробовал "RealWorld Cursor Editor", то для курсора формата .ani, нужно использовать

Спойлер
/*
Файл курсора - Test.ani (создан через RealWorld Cursor Editor).
*/

unsigned char cursorsData[4362] = {0x52, 0x49, 0x46, 0x46, 0x02, 0x11, 0x00, 0x00, ... };
HCURSOR cursor = static_cast<HCURSOR>(CreateIconFromResourceEx(cursorsData, 4362, FALSE, 0x00030000, 32, 32, LR_DEFAULTCOLOR | LR_DEFAULTSIZE));
                                      
/*
Для функции CreateIconFromResourceEx здесь третий параметр FALSE, как и должно быть, так как согласно MSDN - 
"Indicates whether an icon or a cursor is to be created. If this parameter is TRUE, an icon is to be created. If it is FALSE, a cursor is to be created."
*/
                                      
/*
HotSpot определяется нормально. А значит, этот вариант, с курсорами из RealWorld Cursor Editor, - подходит.
*/

 

 

Если попытаться создать курсор в Microsoft Visual Studio размеров 256х256, чтобы на выходе, при его загрузке в качестве HCURSOR, получить сглаженные красивые края (Windows уменьшит любой размер больший чем 48х48 до 48х48, используя попытку сглаживания), то увы, ничего не выйдет, курсор будет искажен, то есть будет неправильно произведена подгонка до меньшего размера.

С курсорами RealWorld Cursor Editor можно сразу создать курсор размеров 32х32 или 48х48, и его края уже будут сглажены. в Microsoft Visual Studio такого не сделать.

Вывод, нужно использовать либо программу "RealWorld Cursor Editor", либо тестировать и пробовать другие ей подобные.

 

 

*************************************************************************************

По поводу перенаправления поиска DLL, - на самом деле не так все и сложно.

1 - Нужно создать манифест для приложения, которое будет использовать какую-нибудь DLL. В манифесте указать зависимоть от какой-то определенной сборки (assembly manifest).

2 - Нужно создать сам манифест сборки (assembly manifest).

3 - Нужно создать конфигурационный файл, поместив его в папку с EXE файлом приложения. В этом конфигурационном файле указать дополнительную папку для поиска манифеста сборки (assembly manifest).

4 - В папку с DLL нужно поместить манифеста сборки (assembly manifest).

 

Все эти операции описаны на MSDN, сначало ничего не понятно, но под конец, все вкладывается в одну картину. Там же описывается как писать на XML.

MSDN - side-by-side-assemblies

 

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.