Наверно боян, но что то я уже второй день не могу разобраться с этой проблемой. Работаю с библиотеками недавно
В обычной 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
}
}
Здравствуйте, 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;
Здравствуйте, 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 приложения.
Здравствуйте, 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
Это так, к сведению
Просто надо принять за правило, везде где используется 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-и библиотеках, для весомости дистриба.
А потом начнется, одна библиотека с этой версией собрана другая с другой.