Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Ресурсы в DLL  (Прочитано 12240 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 27-07-2011 06:13 » 

 вопрос. Имелся в солюшене проект с диалогом и другими ресурсами (в частности с курсорами). Добавил я проект для DLL , на все нужные хедеры завёл ссылки в дерево . А на ресурсы то не сошлёшься, пришлось копировать дерево ресурсов. Всё бы и ничего, но ведь легко забыть снова сделать копию, когда в том проекте я что-то подправлю. Как-то это решается более удобно ?
« Последнее редактирование: 28-07-2011 03:25 от Алексей1153++ » Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 27-07-2011 11:19 » 

Лёш, ща такие запарки на работе... Последние часы остались, а дел "боюсь до октябрских не управимся" (с).

Чуть конкретней, что именно ты хочешь сделать? Общие ресурсы для DLL и EXE? Это MFC? Динамическая подгрузка ресурсов не подойдёт?

зы в 14:00 (GMT+1) ухожу на совещание... часа на два.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 27-07-2011 14:27 » 

Джон, не, всё проще. Первый проект - это программулька с диалогом. Второй проект являет собой DLL , в недрах которой создаётся экземпляр класса диалога, а также из DLL экспортированы функции, чтобы "жать на кнопки" (но это тут ни при чём). Так вот, чтобы из DLL-проекта использовать класс-диалог, пришлось туда тащить ссылки на все нужные исходники из первого проекта. Это ладно, несложно. Но вот пришлось ещё и ресурсы тащить, а это я смог сделать только копированием дерева ресурсов. А хотелось бы что-то вроде

#include "..\FirstProject\resources.rc"
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 27-07-2011 20:37 » 

Лёш, "тащить дерево ресурсов" - явно не программирование, или? Те ты просто скопировал. И теперь у тебя два одинаковых ресурса. Так?

Лёш, я так понимаю и DLL и Первый проект работают с одинаковыми ресурсами. Так? Оба MFC. Так?

Так сделай чисто ресурсную DLL и подгружай её в первый и второй проект. Делается это элементарно:

в InitInstance() делаешь след.

Код: (C++)
                HINSTANCE hRes = LoadLibrary(stResDLLPath);
                if(hRes)
                {
                        AfxSetResourceHandle(hRes);
                }


Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 28-07-2011 03:29 » 

хм, ну, вроде можно так попробовать. Спасибо
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 28-07-2011 06:17 » new

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

Однако при сборке в DLL и EXE окажутся независимые (хотя и одинаковые) копии ресурса. Если этого не надо, то сделать, как сказал Джон.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 28-07-2011 07:34 » 

В solution в проекте, где нужна копия, можно добавить уже существующие файлы одного проекта в другой. Тогда физическое изменение файла будет учитываться во всех использующих этот файл проектах.
да, так и хочется. Но есть одно "но" - если добавить, указав на существующие файлы, то в проектах в файлах resource.h окажутся одинаковые идентификаторы (что хорошо) с разными значениями (что нехорошо). А ведь файлы первого проекта также добавлены во второй в виде ссылок. И тогда, из DLL вызываем диалог (код которого - в первом проекте), а диалог пытается использовать идентификаторы первого же проекта, тогда как ресурсы описаны для второго. Идентификаторы в общем случае получаются кривыми, приложение падает. Вроде я ничего тут не перепутал Улыбаюсь Именно из-за этого и пришлось копировать ресурсы - тогда неважно, из какого файла resource.h будут взяты значения идентификаторов, так как в обоих проектах есть одинаковые ресурсы.
И ещё одно "но" - диалоги то не в отдельных файлах описаны...



Добавлено через 11 часов, 14 минут и 42 секунды:
Джон, с DLL прокатило в плане диалоговых ресов. А вот иконки и курсоры не хотят грузится. Видимо, для них придётся ссылки на файлы сделать всё же ?
« Последнее редактирование: 28-07-2011 18:49 от Алексей1153 » Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #7 : 28-07-2011 19:02 » 

Не, Лёш, они у тебя лежат в какой-то папке. Ты просто должен в .rc файле указать относительные пути к этим файлам.

Смотри, я использую такую схему для мултиязычности. Языковые ДЛЛ-ки лежат у меня в подпапке проекта, битмапы и пр. лежат в Проект\res

Тогда путь в языковой ДЛЛ у меня определяется как "..\res\имя.файла", вместо "res\имя.файла". Вот и весь фокус.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 28-07-2011 19:08 » 

Джон, в проекте DLL все файлы на месте.

А при загрузке то путь не используется :

Код:
m_hIcon = theApp.LoadIcon(IDR_CLIENT_ICON);
m_hCur=::LoadCursor(theApp.m_hInstance,MAKEINTRESOURCE(IDC_POINTER));

что-то я не учёл

Добавлено через 11 минут и 23 секунды:
с курсором решилось (theApp.m_ResDLL - инстанс DLL):

Код:
	m_hCur=::LoadCursor(theApp.m_ResDLL,MAKEINTRESOURCE(IDC_POINTER));


с иконками сделал подобно, но там , по-моему, всё равно бардак

Код:
	m_hIcon = LoadIcon(theApp.m_ResDLL,MAKEINTRESOURCE(IDR_CLIENT_ICON));


Добавлено через 14 часов, 41 минуту и 33 секунды:
Проблема!

Есть COM.dll (содержит компонент) и есть RES.dll (содержит ресурсы)

Если COM.dll используется из екселя, то текущий путь - нечто вроде C:\.....\Office\
Код библиотеки COM.dll пытается подгрузить RES.dll (LoadLibrary(L"RES.dll")) , но текущий путь оказывается неверным . Хотя RES.dll лежит около COM.dll

Как это победить ? Где взять путь к RES.dll ?

Но ведь RES.dll
« Последнее редактирование: 29-07-2011 10:01 от Алексей1153 » Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 29-07-2011 14:40 » 

Алексей1153++, если они лежат рядом, я в таких случаях анализирую путь вызывающего модуля и при загрузке вызываемого подставляю этот путь.

Как добыть путь DLL из неё самой не знаю.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 29-07-2011 16:53 » 

Алексей1153++, если они лежат рядом, я в таких случаях анализирую путь вызывающего модуля и при загрузке вызываемого подставляю этот путь.
я также, но тут дело в том, что путь инстанса такой, какой был а загружающего DLL модуля. В данном случае это эксель в папке office , а сама DLL лежит совершенно в другом месте, путь к ней где-то в реестре. Может быть, есть некие стандартные функции  - достать путь к "телу" DLL COM-объекта?

А я пока убрал ресурсную DLL... А то я там застрял

Добавлено через 1 час, 41 минуту и 37 секунд:
усё, жестокий тупняк немного отпустил ))

вот тут путь прописан
HKEY_CLASSES_ROOT\CLSID\{9F60A0F1-EC4A-46F4-8965-5D03BBEA92A8}\InprocServer32\default

Добавлено через 4 минуты и 11 секунд:
вот самая полезная из книжек, найденных мной на эту тему ))
https://club.shelek.ru/download.php?id=77

Добавлено через 1 час, 24 минуты и 45 секунд:
добыл путь так:

Код:
//будет содержать путь к DLL, оканчивающийся бэкслешем
std::wstring m_pathToDLL__;

{
CLSID clsid;
std::wstring temp_pathToDLL__;

CLSIDFromProgID(L"TMV1C_Component.SlavedClient", &clsid);

std::wstring strGuid=L"{00000000-0000-0000-0000-000000000000}";
if(sizeof(clsid.Data4)==8)
{
swprintf_s(&strGuid[0],strGuid.size()+1,L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"
,clsid.Data1,clsid.Data2,clsid.Data3
,clsid.Data4[0],clsid.Data4[1]
,clsid.Data4[2],clsid.Data4[3]
,clsid.Data4[4],clsid.Data4[5]
,clsid.Data4[6],clsid.Data4[7]
);

std::wstring key=L"CLSID\\"+strGuid;
key+=L"\\InprocServer32";

HKEY hk=0;
if(ERROR_SUCCESS==RegOpenKey(HKEY_CLASSES_ROOT,key.c_str(),&hk))
{
temp_pathToDLL__.resize(MAX_PATH,0);
LONG size_in_bytes=(temp_pathToDLL__.size()+1)*sizeof(temp_pathToDLL__[0]);

if(ERROR_SUCCESS==RegQueryValue(hk,0,&temp_pathToDLL__[0],&size_in_bytes) && size_in_bytes)
{
int pos=temp_pathToDLL__.find_last_of(L'\\');
if(pos!=temp_pathToDLL__.npos)
{
temp_pathToDLL__.erase(pos+1);
m_pathToDLL__=temp_pathToDLL__;
}
}
RegCloseKey(hk);
}
}
}
::MessageBox(0,m_pathToDLL__.c_str(),L"path",MB_SYSTEMMODAL);


« Последнее редактирование: 29-07-2011 19:59 от Алексей1153 » Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines