Вызов из Dll метода родителя
typedef void (WINAPI * FUNC)();
class CClassDLL
{
private:
FUNC adrRun;
public:
CClassDLL(){};
virtual ~CClassDLL(){};
virtual void SetAdrFunction(FUNC *adr);
};
extern "C" __declspec(dllexport) CClassDLL* CreateDLL();
//-------------------------------------------------------------
//DLL.cpp
#include "stdafx.h"
#include "DLL.h"
#include "DLLExport.h"
...
void CClassDLL::SetAdrFunction(FUNC *adr)
{
adrRun = (FUNC)adr;
adrRun(); // попытка вызвать метод родителя
}
CClassDLL* CreateDLL()
{
return new CClassDLL;
}
//-------------------------------------------------------------
//Exe.cpp
...
#include "DLLExport.h"
typedef CClassDLL* (*PCreate)();
...
int CExeApp::outSoo()
{
::MessageBox(NULL,"Текст сообщения","Сообщение",NULL);
return -1;
}
void CExeApp::OnTest()
{
HMODULE hLib = ::AfxLoadLibrary("DLL.dll");
if(hLib == NULL)
{
::MessageBox(NULL,"Нет библиотеки DLL.dll","Ошибка",NULL); return;
}
PCreate pCreateFn = (PCreate)::GetProcAddress(hLib, "CreateDLL");
if(!pCreateFn)
{
::MessageBox(NULL,"Нет функции CreateDLL() в библиотеке DLL.dll","Ошибка",NULL);
::AfxFreeLibrary(hLib);
return;
}
CClassDLL *pA = pCreateFn();
pA->SetAdrFunction((FUNC*)&outSoo());
::AfxFreeLibrary(hLib);
}
2) не путай функцию и метод класса, для твоего примера метод должен быть статическим;
3) запись pA->SetAdrFunction((FUNC*)&outSoo());
обозначает, что ты передаешь в SetAdrFunction адрес значения, возвращаемого outSoo(), т.е. адрес временного значения типа int.
А вообще-то можно воспользоваться поиском, тема обсуждалась не один десяток раз.
Последний раз - вчера:
http://forum.codenet.ru/showthread.php?s=&threadid=23809
1) что-то я тут никакой родственности не нашел;
2) не путай функцию и метод класса, для твоего примера метод должен быть статическим;
3) запись pA->SetAdrFunction((FUNC*)&outSoo());
обозначает, что ты передаешь в SetAdrFunction адрес значения, возвращаемого outSoo(), т.е. адрес временного значения типа int.
А вообще-то можно воспользоваться поиском, тема обсуждалась не один десяток раз.
Последний раз - вчера:
http://forum.codenet.ru/showthread.php?s=&threadid=23809
Если исправляю на то, что закоммениторвано /**/, то все работает. Но стоит переделать на вызов
функции outSoo() с параметром outSoo(char *soo), то выводится окно сообщения, а после его
закрытия появляется исключение. Непойму, в чем дело...
/* typedef void (WINAPI * FUNC)(); */
typedef void (WINAPI * FUNC)(char *soo);
class CClassDLL
{
private:
FUNC adrRun;
public:
CClassDLL(){};
virtual ~CClassDLL(){};
virtual void SetAdrFunction(FUNC adr);
};
//------------------------------------------------------------------
//DLL.cpp
void CClassDLL::SetAdrFunction(FUNC adr)
{
adrRun = adr;
}
void CClassDLL::RunFunction()
{
/* adrRun(); */
adrRun("Сообщение от DLL");
}
//--------------------------------------------------------------------
//Exe.h
class CExeApp : public CWinApp
{
...
/* static void outSoo(); */
static void outSoo(char *soo);
};
//----------------------------------------------------
//Exe.cpp
/* void CExeApp::outSoo() */
void CExeApp::outSoo(char *soo)
{
/* ::MessageBox(NULL,"Текст сообщения","Сообщение",NULL); */
::MessageBox(NULL,soo,"Сообщение",NULL);
}
void CExeApp::OnTest()
{
...
CClassDLL *pA = pCreateFn();
pA->SetAdrFunction((FUNC)outSoo);
...
}
1. Вызвать нестатическую функцию?
2. Присвоить значение нестатической переменной?
А можно ли обойти ошибку:
static CString s;
А возможно ли из статической функции:
1. Вызвать нестатическую функцию?
Говорили же про сленг...
Вот непонятно, что ты имеешь в виду под определением "статической функции".
Глобальную функцию объявленную, как static:
static void func();
или статический метод член класса:
static Class::func();
В первом случае не вижу проблем, во втором - передаешь экземпляр, и тоже нет проблем:
struct A
{
void nonstatic();
static void func()
{
// здесь получаем ссылку/указатель на экземпляр
pInst->nonstatic(); // вызываем
}
};
2. Присвоить значение нестатической переменной?
Вопрос не понят. Что ты подразумеваешь под нестатической переменной?
А в чем проблема?
int a;
a = 5;
А можно ли обойти ошибку:
static CString s;
Я здесь ошибки не вижу.
class A
{
CString s;
static CString ss; //error LNK2001: unresolved external symbol "public: static class ATL::CStringT<char,class StrTraitMFC_DLL<char,class ATL::ChTraitsCRT<char> > > A::ss" (?ss@A@@2V?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@A)
int f1(); // мне нужен нестатический
static int f2();
}
A::int f2()
{
f1(); // error C2352: 'A::f1' : illegal call of non-static member function
s = "aaaaaaa"; // error C2597: illegal reference to non-static member 'A::s'
}
Извиняюсь...
class A
{
CString s;
static CString ss; //error LNK2001: unresolved external symbol "public: static class ATL::CStringT<char,class StrTraitMFC_DLL<char,class ATL::ChTraitsCRT<char> > > A::ss" (?ss@A@@2V?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@A)
int f1(); // мне нужен нестатический
static int f2();
}
A::int f2()
{
f1(); // error C2352: 'A::f1' : illegal call of non-static member function
s = "aaaaaaa"; // error C2597: illegal reference to non-static member 'A::s'
}
Здесь дело в том что переменная ss (фашисты однако) здесь только объявлена... а должна быть еще определена...обычно в cpp файле...хотя у кого как...
CString A::ss;
class A
{
int f1(); // мне нужен нестатический
static int f2();
}
A::int f2()
{
f1(); // error C2352: 'A::f1' : illegal call of non-static member function
s = "aaaaaaa"; // error C2597: illegal reference to non-static member 'A::s'
}
Так не выйдет. Я же говорил, нужен экземпляр.
Т.е. ты должен либо передавать в статический метод ссылку/указатель на экземпляр класса и вызывать метод с явным указанием этого экземпляра:
{
instance.f1();
instance.s = "aaaaaaa";
}
либо получать экземпляр каким-либо иным образом, например из какого-то глобального объекта.