Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как в CPropertySheet добавить CPropertyPage из DLL 
V
    Опции темы
Bukmop
  Дата 1.6.2006, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



Помогите в CPropertySheet добавить CPropertyPage из DLL

TestEXE.cpp
Код

#include "TestDLL.h"

{
CPropertySheet sheet("Property Sheet");
CTest1 p1;
sheet.AddPage(&p1);
sheet.DoModal();
}


TestDLL.h
Код

class AFX_EXT_CLASS CTest1 : public CPropertyPage
{
DECLARE_DYNAMIC(CTest1)
DECLARE_MESSAGE_MAP()
public:
CTest1() : CPropertyPage( CTest1::IDD ) {};
enum { IDD = IDD_TEST1 };
virtual BOOL OnInitDialog();
};

TestDLL.cpp
Код

#include "TestDLL.h"

IMPLEMENT_DYNAMIC(CTest1, CPropertyPage)
BEGIN_MESSAGE_MAP(CTest1, CPropertyPage)
END_MESSAGE_MAP()

BOOL CTest1::OnInitDialog()
{
CPropertyPage::OnInitDialog();
...
return(TRUE);
}

TestDLL.rc
Код

IDD_TEST1 DIALOGEX 0, 0, 270, 170
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Test-1"
FONT 8, "MS Sans Serif"
BEGIN
    CTEXT           "",IDC_TEXT,10,10,250,12
END
    

Это сообщение отредактировал(а) Bukmop - 1.6.2006, 18:14
PM MAIL   Вверх
DeadSoul
Дата 1.6.2006, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Единственная проблема там - ресурсы. Вот пример для родительского диалога в ехе, а child-ового в dll
Код

HINSTANCE hInstExe = AfxGetResourceHandle(); 
AfxSetResourceHandle(::GetModuleHandle(“mdlldll”));
pDlg2->Create(IDD_DLG2, pDlg );
AfxSetResourceHandle(hInstExe);


Делай аналогично 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Bukmop
Дата 1.6.2006, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



Не совсем понял, куда это девать.
Поэтому уточнил задачу.
 
PM MAIL   Вверх
Earnest
Дата 1.6.2006, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



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

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

Экспортировать можно 2 способами:

1) __declspec( dllimport )\__declspec( dllexport ):
экспортируемая сущность должна быть объявлена в своем модуле как __declspec( dllexport ),
а в чужом - как __declspec( dllimport )
Проще всего это достигается макросом:

Код

#ifdef _TESTDLL
   #define TEST_API __declspec(dllexport)
#else
   #define TEST_API __declspec(dllimport)
#endif

class CTestPropPaget: public CPropertyPage
{
public:
   TEST_API CTestPropPage();
   TEST_API ~CTestPropPage();

};

// или, чтобы экспортировать весь класс

class TEST_API CTestPropPage: public CPropertyPage
{
public:
   CTestPropPage();
   ~CTestPropPage();
};


Макросимвол _TESTDLL нужно определить для всего проекта TestDll (в свойствах проекта)

2) def - файл. Просто поместить имена всех нужных функций в def-файл.
На самом деле это не очень просто, т.к. имена должны быть декорированными, т.е. такими, как их видит линкер. Но можно сделать так: сначала ничего никуда не пишем, а просто пытаемся собрать приложение. Линкер будет орать насчет неразрешенных ссылок. Акуратно копируем имена, которые он хочет, прямо из сообщения об ошибке, и помещаем их в def- файл. Выглядеть будет примерно так:

Код

LIBRARY      "TestDLL"
EXPORTS
?GetThisMessageMap@CTestPropPage@@KGPBUAFX_MSGMAP@@XZ


Второй способ плох тем, что при малейшем изменении интерфейса экспортируемых функций нужно менять запись в def-файле. Даже просто при изменении доступа с public на, скажем, protected...
Сдругой стороны, есть сущности, которые иначе как через def-файл не проэкспортируешь.
  

Это сообщение отредактировал(а) Earnest - 1.6.2006, 17:16


--------------------
...
PM   Вверх
Bukmop
Дата 1.6.2006, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



Подобное, я уже пробовал, используя встроенный в MFC макрос AFX_EXT_CLASS. Но я понял так, что это для экспорта класса на стадии компиляции, а не выполнения. Короче, линкер по-прежнему ругался. 
PM MAIL   Вверх
DeadSoul
Дата 1.6.2006, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Цитата(Earnest @  1.6.2006,  17:13 Найти цитируемый пост)
DeadSoul имел в виду случай, когда ресурс страницы загружается из другого модуля, у тебя же там весь код, как я понимаю

Там весь код включая и PropertySheet? 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Earnest
Дата 1.6.2006, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Значит, что-то ты сделал неправильно.
Если DLL одна, то вполне можно обойтись макросом AFX_EXT_CLASS, только чтобы он заработал, DLL должна быть создана как ExtensionDLL (кроме всего прочего, в проект добавляется макросимвол _AFXEXT, а без него, конечно, не получится).

В общем, опиши, что ты сделал, и какие ошибки дает линкер.

Добавлено @ 18:19 
Цитата(DeadSoul @  1.6.2006,  19:14 Найти цитируемый пост)
Там весь код включая и PropertySheet?  

Нет, как я понимаю, код Property Sheet находится в EXE.
 


--------------------
...
PM   Вверх
Bukmop
Дата 1.6.2006, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



Earnest, ты как всегда всё правильно понимаешь, а я очень извиняюсь за ложную информацию (сам уже начал путаться в результатах попыток, голова уже плохо соображает). В том случае всё скомпилировалось, но вытащить страницу не получилось.
Делал так:
Код

HINSTANCE hInst1=::LoadLibrary("Test1.dll");
if(hInst1)
    {
    CTest1* p1=(CTest1*)::GetProcAddress(hInst1,"СTest1");
    if(p1)
        sheet.AddPage(p1);
    }

Получал p1=NULL;

А если бы делал всё правильно – то всё бы работало (чудес-то не бывает).   

Это сообщение отредактировал(а) Bukmop - 1.6.2006, 19:08
PM MAIL   Вверх
Earnest
Дата 1.6.2006, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Да уж, зову не знамо кого... smile  А оно и не отзывается почему-то...
Вообще-то при такой связи с DLL ее лучше не динамически подключать, а прямо к проекту, чтобы еще линкер все ссылки разрешил.
Так ты разобрался в конце концов? 


--------------------
...
PM   Вверх
Bukmop
Дата 1.6.2006, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



Я тычусь как слепой котёнок, т.к. не понимаю, как правильно сделать, сижу и перебираю все мыслимые и немыслимые варианты (пока впустую).
Вот последний:
DLL
Код

CTest1* AFX_EXT_DATA pTest1=NULL;

DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
    pTest1=new CTest1;
    }
}

EXE
Код

HINSTANCE hInst1=::LoadLibrary("Test1.dll");
CTest1* p1=(CTest1*)::GetProcAddress(hInst1,"pTest1");

 
Благодарю за терпение, по себе знаю как трудно с такими... Но мне уже начинает казаться, что я хочу невозможного. 

Это сообщение отредактировал(а) Bukmop - 1.6.2006, 19:25
PM MAIL   Вверх
DeadSoul
Дата 1.6.2006, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Bukmop, так ответь на простые вопросы:
1. Где находится твой ProperySheet( dll\exe )?
2. Где находится PropertPage( dll\exe )?
3. Где ты создаешь твой PropertySheet( dll\exe )?


P.S. LoadLibrary тут не нужен 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Bukmop
Дата 1.6.2006, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



DeadSoul
1. exe
2. dll
3. exe
 
P.S. Смысл: Есть dll-ки - есть странички. Нет dll-ек - нет страничек. Изменились свойства dll-ек - не нужно трогать exe-ник.
   

Это сообщение отредактировал(а) Bukmop - 1.6.2006, 19:43
PM MAIL   Вверх
DeadSoul
Дата 1.6.2006, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



4. Как ты получаешь доступ к классам\функция в dll
- прописываешь в exe все необходимые *.h+*.lib
- LoadLibrary+GetProcAddress 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Bukmop
Дата 1.6.2006, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



4. Пытался - LoadLibrary+GetProcAddress.

lib мне не подходит, т.к. при изменении dll-ки придётся перекомпилировать exe-шник.
 

Это сообщение отредактировал(а) Bukmop - 1.6.2006, 21:01
PM MAIL   Вверх
Earnest
Дата 2.6.2006, 06:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Так бы сразу и сказал, что тебе обязательно нужно загружать DLL динамически.
Тогда действительно, LoadLibrary + GetProcAddress. НО: получить через GetProcAddress можно только то, что есть в таблице экспорта. Поскольку экспортировать придется через def-файл, то с классами возиться сложно (надо ведь декорированные имена записывать для всех функций),
Поэтому делаем так:
1) К EXE ничего не подключаем (h-файла с описанием страницы), придется ему довольствоваться интерфейсом CPropertyPage.
2) В DLL создаем функцию CPropertyPage* CreatePage(/* нужные параметры */). Причем объявляем ее как extern "C", чтобы не мучиться с именами. И записываем в def-файл. Вот только не помню, это будет просто CreatePage или _CreatePage, нужно уточнить. Впрочем, с неправильной записью в def-файле DLL не соберется.Еще можно уточнить имя с помощью map-файла.
3) Дальше все как ты делал, GetProcAddress c тем именем, что записано в def.
4) Только теперь у тебя выделена память под страницу, поэтому не забудь ее удалить после DoModal.
5) Не уверена, что по delete будет вызван правильный деструктор. Я бы проверила, поставив туда точку прерывания...

 


--------------------
...
PM   Вверх
DeadSoul
Дата 2.6.2006, 10:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Цитата(Earnest @  2.6.2006,  06:30 Найти цитируемый пост)
Причем объявляем ее как extern "C", чтобы не мучиться с именами. И записываем в def-файл

Достаточно второго.

Цитата(Earnest @  2.6.2006,  06:30 Найти цитируемый пост)
5) Не уверена, что по delete будет вызван правильный деструктор. Я бы проверила, поставив туда точку прерывания...

Нужно добавить вторую функцию DestroyPage

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


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Earnest
Дата 2.6.2006, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Цитата(DeadSoul @  2.6.2006,  11:19 Найти цитируемый пост)
Достаточно второго.

Не совсем. 
Запись в def - необходима, без extern "C" можно обойтись, но имена C++ функций довольно сложно декорируются, именно декорированные имена и надо указывать в def (а потом в GetProcAddress). Если в def написать просто CreatePage, DLL не соберется (с точки зрения линкера, такой функции нет).

Цитата(DeadSoul @  2.6.2006,  11:19 Найти цитируемый пост)
Нужно добавить вторую функцию DestroyPage
Вчера вечером попробывал. Там действительно неслабые траблы(похоже, с ресурсами). 

Хоть и написала сама, что проверить надо, но как-то это странно: ведь деструктор-то виртуальный. Тогда что, и другие виртуальные ф-и работать не будут? Как же интересно COM работает на одних виртуальных вызовах без всяких экспортов...
Наверняка "трабла" не в этом. И не в ресурсах. Не может быть там никаких проблем, если все правильно делать. 


--------------------
...
PM   Вверх
DeadSoul
Дата 2.6.2006, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Цитата(Earnest @  2.6.2006,  11:51 Найти цитируемый пост)
Цитата(DeadSoul @  2.6.2006,  11:19 )
Достаточно второго.
Не совсем. 
Запись в def - необходима, без extern "C" можно обойтись, но имена C++ функций довольно сложно декорируются, именно декорированные имена и надо указывать в def (а потом в GetProcAddress). Если в def написать просто CreatePage, DLL не соберется (с точки зрения линкера, такой функции нет).

У меня почему-то собралось и успшно работало....


Цитата(Earnest @  2.6.2006,  11:51 Найти цитируемый пост)
Цитата(DeadSoul @  2.6.2006,  11:19 )
Нужно добавить вторую функцию DestroyPage
Вчера вечером попробывал. Там действительно неслабые траблы(похоже, с ресурсами). 
Хоть и написала сама, что проверить надо, но как-то это странно: ведь деструктор-то виртуальный.

Выделять\освобождать память нужно внутри одного модуля, т.е. не рекомендуется выделять память в exe, а осовобождать в dll(и наоборот)


Цитата(Earnest @  2.6.2006,  11:51 Найти цитируемый пост)
Как же интересно COM работает на одних виртуальных вызовах без всяких экспортов...

Это абсолютно другая история.


Цитата(Earnest @  2.6.2006,  11:51 Найти цитируемый пост)
Наверняка "трабла" не в этом. И не в ресурсах. Не может быть там никаких проблем, если все правильно делать. 

В них. Только в них. Готов показать кодом. 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Earnest
Дата 2.6.2006, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Цитата(DeadSoul @  2.6.2006,  12:56 Найти цитируемый пост)
Выделять\освобождать память нужно внутри одного модуля, т.е. не рекомендуется выделять память в exe, а осовобождать в dll(и наоборот)

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

Цитата(DeadSoul @  2.6.2006,  12:56 Найти цитируемый пост)
Это абсолютно другая история.

В чем это другая? Виртуальные функции и в африке виртуальные... Проблема с удалением страницы действительно может быть не в вызове деструктора (там как раз все должно сойтись), а в освобождении памяти.
Цитата(DeadSoul @  2.6.2006,  12:56 Найти цитируемый пост)
В них. Только в них. Готов показать кодом.  

Давай, только желательно покороче.  smile Если про ресурсы. Если про delete - не надо, согласна, что проблемы могут быть. 


--------------------
...
PM   Вверх
DeadSoul
Дата 2.6.2006, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Цитата(Earnest @  2.6.2006,  12:32 Найти цитируемый пост)
Цитата(DeadSoul @  2.6.2006,  12:56 )
Выделять\освобождать память нужно внутри одного модуля, т.е. не рекомендуется выделять память в exe, а осовобождать в dll(и наоборот)
Это может быть, но все равно не совсем понятно...
Там действительно есть какие-то проблемы, но мы их как-то обошли... уже не помню... ясно, что хип должен быть общий, тогда проблем нет. 

Насколько помню все зависит от линковки рантайма(динамическая\статическая)


Цитата(Earnest @  2.6.2006,  12:32 Найти цитируемый пост)
Цитата(DeadSoul @  2.6.2006,  12:56 )
Это абсолютно другая история.
В чем это другая? Виртуальные функции и в африке виртуальные... Проблема с удалением страницы действительно может быть не в вызове деструктора (там как раз все должно сойтись), а в освобождении памяти.

Так у меня все падает при попытке создания страницыsmile


Цитата(Earnest @  2.6.2006,  12:32 Найти цитируемый пост)
Цитата(DeadSoul @  2.6.2006,  12:56 )
В них. Только в них. Готов показать кодом.  
Давай, только желательно покороче.   Если про ресурсы

Сейчас нарисуем
 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
DeadSoul
Дата 2.6.2006, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Вот пример(Компилятор - 8-ая студия).

P.S.  Заметь extern "C" нигде нет 

Присоединённый файл ( Кол-во скачиваний: 6 )
Присоединённый файл  TestPropPage.rar 62,74 Kb


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Bukmop
Дата 2.6.2006, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



Нашёл два отличия с тем, что делал я:
1. Мой EXE-шник - Use MFC in a Static Library
2. Моя DLL-ка - MFC extension DLL

Но и после всего этого выдаёт - "A required resource was unavailable".
 
PM MAIL   Вверх
DeadSoul
Дата 2.6.2006, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Цитата(Bukmop @  2.6.2006,  16:15 Найти цитируемый пост)
Но и после всего этого выдаёт - "A required resource was unavailable".


Bukmop, я знаю. Я и хотел показать, что там проблема ровно одна - ресурсы.

Добавлено @ 16:25 
Сейчас покопаюсь еще. Может смогу ресурсы победить.

Добавлено @ 16:33 
В общем, выход ровно один. Отнаследоватся от CPropertySheet и переопределить BuildPropPageArray 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Bukmop
Дата 2.6.2006, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



СПАСИБО!
Твой вариант я работать заставил.
Код

CPropertyPage* page=funcPtr();
page->m_psp.hInstance=hMod;

И он таки нашёл ресурс.

Теперь буду воевать со своим Static Library.
   

Это сообщение отредактировал(а) Bukmop - 2.6.2006, 17:03
PM MAIL   Вверх
Earnest
Дата 2.6.2006, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



DeadSoul, не могу загрузить твой проект, т.к. у меня нет 8й студии, а в 7 эта зараза грузиться не желает... 
Так что придется всухую...

Цитата(Bukmop @  2.6.2006,  17:15 Найти цитируемый пост)
1. Мой EXE-шник - Use MFC in a Static Library
2. Моя DLL-ка - MFC extension DLL

Это неправильно, все должно использовать Shared MFC DLL, это приведет к Shared RunTime DLL. Тогда, по идее проблем с памятью не должно быть.
Кроме того, динамически загружаемая DLL лучше делать Regular, хотя все равно не понимаю, откуда проблемы с ресурсами.

... Посмотрела код ...  Как насчет вот этого?

Код

//TODO: If this DLL is dynamically linked against the MFC DLLs,
//        any functions exported from this DLL which call into
//        MFC must have the AFX_MANAGE_STATE macro added at the
//        very beginning of the function.
//
//        For example:
//
//        extern "C" BOOL PASCAL EXPORT ExportedFunction()
//        {
//            AFX_MANAGE_STATE(AfxGetStaticModuleState());
//            // normal function body here
//        }

В смысле, в начало кода CreatePage нужно вставить
 AFX_MANAGE_STATE(AfxGetStaticModuleState());

Не знаю, почему extern "C" перестал быть нужен... раньше (в 6-ке) было нужно ... 


--------------------
...
PM   Вверх
DeadSoul
Дата 2.6.2006, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Цитата(Earnest @  2.6.2006,  17:10 Найти цитируемый пост)
DeadSoul, не могу загрузить твой проект, т.к. у меня нет 8й студии, а в 7 эта зараза грузиться не желает... 
Так что придется всухую...

Посмотри  просто cpp\h\def файлы. Там добавления к стандартным проектам минимальны.

Цитата(Earnest @  2.6.2006,  17:10 Найти цитируемый пост)
В смысле, в начало кода CreatePage нужно вставить
 AFX_MANAGE_STATE(AfxGetStaticModuleState());

Не спасет. Доступ к ресурсу нужен в момент создания окна, а окно создается совсем не там
Цитата(Bukmop @  2.6.2006,  16:44 Найти цитируемый пост)
Твой вариант я работать заставил.

Рад за тебя. Я-то слона не заметил.... 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Earnest
Дата 2.6.2006, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Была не права:  лучше делать Extension DLL из-за проблем со картой окон...
Тогда, конечно, AFX_MANAGE_STATE(AfxGetStaticModuleState()) не надо.
Руками сделала проекты в 7 студии (диалоговое приложение + extension DLL), добавила туда файлы, все нормально трудится. Желаете проект?

Добавлено @ 17:30 
Цитата(DeadSoul @  2.6.2006,  18:22 Найти цитируемый пост)
Не спасет. Доступ к ресурсу нужен в момент создания окна, а окно создается совсем не там

Меня спасло, но потом пошли ASSERTы из-за WndMap, и пришлось переделывать на Extension DLL. 
  

Это сообщение отредактировал(а) Earnest - 2.6.2006, 17:31


--------------------
...
PM   Вверх
Bukmop
Дата 2.6.2006, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



Earnest, у меня тоже 7.1, но т.к. в проекте нет ничего навороченного я просто в файлах vcproj исправил Version="8,00" на "7.10", а в sln ...Format Version 9.00 на 8.00
И VS это всё прекрасно переварила.

А проблема с ресурсами видимо из-за того, что сама Page  крейтится уже в Sheet-е. 

(Безобразие!!! Мало того, что до четырёх часов вообще не мог достучаться до форума. И сейчас перебои. Не успеваю за жизнью.) 

Проект конечно желаю!
 

Это сообщение отредактировал(а) Bukmop - 2.6.2006, 17:44
PM MAIL   Вверх
Earnest
Дата 2.6.2006, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Bukmop, нет там проблем: я просто сделала свой проект и добавила туда файлы, все получилось. Вот проект, под 7.1.
А насет экспорта я тоже поняла: DeadSoul использовал нумерацию (@1). Действительно, в этом случае линкер как-то без декораций обходится, но я так никогда не делала, поэтому и забыла  smile  

Упс! Не глядя заархивировала прямо с объектниками... То смотрю никак загрузиться не может. 

Это сообщение отредактировал(а) Earnest - 2.6.2006, 17:56

Присоединённый файл ( Кол-во скачиваний: 8 )
Присоединённый файл  DeadSoul.rar 121,65 Kb


--------------------
...
PM   Вверх
Bukmop
Дата 2.6.2006, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



Ужас! Это получается, что я почти неделю стоял на ушах, дошёл до полного маразма и Вас на два дня озадачил. И всё только потому, что  у меня основной проект - Static (так уж давно повелось, таковы были требования).

И что теперь делать? Я так понял, что в Static - это без шансов.

Спасибо всем за помощь и глубокие знания.
Надеюсь, я Вам не мешал (ШУТКА).
  

Это сообщение отредактировал(а) Bukmop - 2.6.2006, 21:42
PM MAIL   Вверх
DeadSoul
Дата 2.6.2006, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Цитата(Bukmop @  2.6.2006,  21:35 Найти цитируемый пост)
И всё только потому, что  у меня основной проект - Static (так уж давно повелось, таковы были требования).

Не только. С моей точки зрения основная трабла была в ресурсах.


Цитата(Earnest @  2.6.2006,  17:48 Найти цитируемый пост)
но я так никогда не делала, поэтому и забыла    

 smile  


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Bukmop
Дата 2.6.2006, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



Цитата(DeadSoul @  2.6.2006,  21:44 Найти цитируемый пост)
С моей точки зрения основная трабла была в ресурсах.

В Static она так и осталась.
 
PM MAIL   Вверх
DeadSoul
Дата 2.6.2006, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Цитата(Bukmop @  2.6.2006,  22:02 Найти цитируемый пост)
Цитата(DeadSoul @  2.6.2006,  21:44 )
С моей точки зрения основная трабла была в ресурсах.
В Static она так и осталась.

При статической линковки MFC-ей?

Добавлено @ 22:18 
Bukmop, ты можешь показать как победил ресурсы? Что и куда ты вписал? 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Bukmop
Дата 2.6.2006, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



DeadSoul, именно при статической линковке MFC-ей я проблему так и не решил. Теперь буду решать, продолжать биться как рыба об лёд или переписывать все ранее созданные библиотеки этого проекта на Shared DLL.

О ресурсах:
В твоём примере (как я уже упоминал) после получения в EXE-ке указателя на "CPropertyPage" из DLL-ки, принудительно поменял HINSTANCE в структуре PROPSHEETPAGE на DLL-ный.
А пример Earnest и так работает.
 
PM MAIL   Вверх
Earnest
Дата 3.6.2006, 06:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Не знаю, получится ли победить ситуацию, если оставить MFC DLL статически прилинкованной. Думаю, что нет. Там ведь в чем дело-то: в MFC есть объект (какой-то трам-пам-пам-state, который синхронизирует доступ к различным ресурсам, в том числе к ресурсам-RC, а также картам окон (т.е. HWND-CWnd) и т.д. Чтобы все работало, нужно, чтобы эта штука была в приложениии одна. Если каждый модуль будет использовать свой экземляр статически прилинкованной MFC DLL, то и этот менеджер у всех будет свой... В общем, не договорятся. Кроме того, использование статической MFC влечет за собой статический RunTime, т.е. у каждого модуля будет свой распределитель памяти, и отсюда проблемы с освобождением "чужой" памяти.
Таким образом, статическая линковка MFC подходит только для приложения, которое состоит из одного EXE. 


--------------------
...
PM   Вверх
DeadSoul
Дата 3.6.2006, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Earnest, почему в твоем примере нет проблем с ресурсами?

Цитата(Bukmop @  2.6.2006,  22:40 Найти цитируемый пост)
О ресурсах:
В твоём примере (как я уже упоминал) после получения в EXE-ке указателя на "CPropertyPage" из DLL-ки, принудительно поменял HINSTANCE в структуре PROPSHEETPAGE на DLL-ный.

В каком месте ты это менял? 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Bukmop
Дата 3.6.2006, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



Код

void CTestExeDlg::OnBnClickedOk()
{
    HMODULE hMod=LoadLibrary(L"TestDLL");
    if ( !hMod )
    {
        AfxMessageBox(_T("Cannot load library"));
        return;
    }

    CreateNewPageFunc funcPtr=reinterpret_cast<CreateNewPageFunc>( GetProcAddress( hMod, "CreateNewPage" ) );
    if ( !funcPtr )
    {
        AfxMessageBox(_T("Cannot find function" ) );
        FreeLibrary( hMod );
        return;
    }

    CPropertyPage* page=funcPtr();
    ASSERT( page );

--->    page->m_psp.hInstance=hMod;

    CPropertySheet sheet;
    sheet.AddPage( page );
    sheet.DoModal();

    delete page;// Данное удаление неверно, нужна функция DeletePage в dll!!!

    FreeLibrary( hMod );
    // TODO: Add your control notification handler code here
    OnOK();
}
 
Строка - 21.
 

Это сообщение отредактировал(а) Bukmop - 3.6.2006, 12:48
PM MAIL   Вверх
DeadSoul
Дата 3.6.2006, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Bukmop, thanks. Как-то не посмотрел, что этот мембер открытый. 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Earnest
Дата 5.6.2006, 08:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Цитата(DeadSoul @  3.6.2006,  12:53 Найти цитируемый пост)
Earnest, почему в твоем примере нет проблем с ресурсами?

 smile  smile  smile  


--------------------
...
PM   Вверх
DeadSoul
Дата 5.6.2006, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Earnest, честно говоря, хотеось бы более развернутый ответ 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Bukmop
Дата 6.6.2006, 09:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 1.6.2006
Где: Москва

Репутация: 2
Всего: 3



DeadSoul, там всё оказалось просто. Earnest использовала MFC extension DLL, а там создаётся CDynLinkLibrary и по этому AfxFindResourceHandle находит нужный ресурс.
 
PM MAIL   Вверх
Earnest
Дата 6.6.2006, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Цитата(DeadSoul @  5.6.2006,  22:33 Найти цитируемый пост)
Earnest, честно говоря, хотеось бы более развернутый ответ  

Извини, я просто не очень поняла, вопрос это или наезд  smile 

В дополнение к тому, что уже сказал Bukmop:
WinAPI, чтобы найти ресурс, нужно указать точно в каком модуле он лежит.
MFC это дело слегка скрывает: ExtensionDLL связываются в цепочку, которая хранится во внутренней глобальной переменной. Когда ты запрашиваешь ресурс, MFC проходит по цепочке, опрашивая все библиотеки по очереди, пока не найдет нужный. 

 


--------------------
...
PM   Вверх
DeadSoul
Дата 6.6.2006, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



BukmopEarnest, спасибо. 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.1716 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.