Проблема с вызовом ресурса из библиотеки
От: J-son  
Дата: 28.06.11 07:38
Оценка:
Наверно боян, но что то я уже второй день не могу разобраться с этой проблемой. Работаю с библиотеками недавно

В обычной DLL, созданной с поддержкой mfc, создал форму в ресурсах. А из функции не могу эту форму вызвать.


class CComputerParams : public CDialog
{
public:
    CComputerParams(CWnd* pParent = NULL);

    enum { IDD = IDD_COMP_PARAMS_DIALOG };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
.......................................................................
}

..........................................................................
extern "C"
{
   __declspec(dllexport) void MyFunction()
   {
       //AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Прочитал, что вроде бы это должно помочь, но толку нет
       
       CComputerParams cmp;
       int res = cmp.DoModal();// возврашает -1
    res = cmp.Create(IDD_COMP_PARAMS_DIALOG, NULL);// а так вываливается на Asserte
   }
}
Re: Проблема с вызовом ресурса из библиотеки
От: J-son  
Дата: 28.06.11 09:37
Оценка:
Здравствуйте, J-son, Вы писали:

JS>Наверно боян, но что то я уже второй день не могу разобраться с этой проблемой. Работаю с библиотеками недавно


JS>В обычной DLL, созданной с поддержкой mfc, создал форму в ресурсах. А из функции не могу эту форму вызвать.



JS>
JS>class CComputerParams : public CDialog
JS>{
JS>public:
JS>    CComputerParams(CWnd* pParent = NULL);

JS>    enum { IDD = IDD_COMP_PARAMS_DIALOG };

JS>    protected:
JS>    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
JS>.......................................................................
JS>}

JS>..........................................................................
JS>extern "C"
JS>{
JS>   __declspec(dllexport) void MyFunction()
JS>   {
JS>       //AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Прочитал, что вроде бы это должно помочь, но толку нет
       
JS>       CComputerParams cmp;
JS>       int res = cmp.DoModal();// возврашает -1
JS>    res = cmp.Create(IDD_COMP_PARAMS_DIALOG, NULL);// а так вываливается на Asserte
JS>   }
JS>}

JS>



Я более менее разобрался, надо вызвать AfxGetResourceHandle().



HINSTANCE hOld = AfxGetResourceHandle();
AfxSetResourceHandle(theApp.m_hInstance);
CComputerParams cmp;
int res = cmp.DoModal();
AfxSetResourceHandle(hOld);


Но все равно не работает.
Смотрю код функции DoModal


hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG);
HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName, RT_DIALOG);
hDialogTemplate = LoadResource(hInst, hResource);


В случае с AfxSetResourceHandle и в случае, когда оно закоментировано, hInst одно и то же (но не 0).
В итоге hResource = 0;
Re: Проблема с вызовом ресурса из библиотеки
От: Baskak Россия  
Дата: 29.06.11 06:26
Оценка: 3 (1)
Здравствуйте, J-son, Вы писали:

JS>В обычной DLL, созданной с поддержкой mfc, создал форму в ресурсах. А из функции не могу эту форму вызвать.



JS>
JS>class CComputerParams : public CDialog
JS>{
JS>public:
JS>    CComputerParams(CWnd* pParent = NULL);

JS>    enum { IDD = IDD_COMP_PARAMS_DIALOG };

JS>    protected:
JS>    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
JS>.......................................................................
JS>}

JS>..........................................................................
JS>extern "C"
JS>{
JS>   __declspec(dllexport) void MyFunction()
JS>   {
JS>       //AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Прочитал, что вроде бы это должно помочь, но толку нет
       
JS>       CComputerParams cmp;
JS>       int res = cmp.DoModal();// возврашает -1
JS>    res = cmp.Create(IDD_COMP_PARAMS_DIALOG, NULL);// а так вываливается на Asserte
JS>   }
JS>}

JS>


Да вроде все правильно делаете, сейчас попробовал повторить то что вы описываете. Как и ожидал, если есть AFX_MANAGE_STATE(AfxGetStaticModuleState()) — то работает, если закомментировать — не работает.
Причем работает даже если вызывать эту функцию ( MyFunction() ) из обычного консольного не-MFC приложения.
Re[2]: Проблема с вызовом ресурса из библиотеки
От: J-son  
Дата: 29.06.11 14:21
Оценка:
Здравствуйте, Baskak, Вы писали:

B>Здравствуйте, J-son, Вы писали:


JS>>В обычной DLL, созданной с поддержкой mfc, создал форму в ресурсах. А из функции не могу эту форму вызвать.



B>Да вроде все правильно делаете, сейчас попробовал повторить то что вы описываете. Как и ожидал, если есть AFX_MANAGE_STATE(AfxGetStaticModuleState()) — то работает, если закомментировать — не работает.

B>Причем работает даже если вызывать эту функцию ( MyFunction() ) из обычного консольного не-MFC приложения.

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

Тем не менее, если повторить мой код во вновь созданной библиотеке (простой, не mfc-шной ), то тоже полезут ошибки из-за того, что, когда создаешь библиотеку, то она автоматически создается с опцией "Use mfc as shared library" (а выбор данной опции при создании не появляется).
То есть, после создания надо поменять в опциях "shared" на "static". В этом случае работает и даже не нужно указывать ресурс через AfxSetResourceHandle
Это так, к сведению
Re: Проблема с вызовом ресурса из библиотеки
От: Druid_swamp  
Дата: 13.07.11 12:39
Оценка: 3 (1)
Просто надо принять за правило, везде где используется MFC и функция вызывается
из другого модуля, необходимо следующее (и тогда не важно shared или static):


#ifdef _AFXDLL
#ifdef _USRDLL
        AFX_MANAGE_STATE(AfxGetStaticModuleState());
#else
        AFX_MANAGE_STATE(AfxGetAppModuleState());
#endif
#endif


_USRDLL — в головном приложении в Preprocessor Definition

PS: про static — Зачем MFC тягать 15 раз в 15-и библиотеках, для весомости дистриба.
А потом начнется, одна библиотека с этой версией собрана другая с другой.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.