[omniORB] Is this doable
Martin J.N. Corino
mcorino@m2c-software.nl
Thu, 11 Mar 1999 09:25:22 +0100
Hi Bing,
Bruce Visscher already answered why this approach does not work.
What you need here is a little inheritance combined with template work.
Let's see...
First create the base for a generic command-object:
class CTCmdBase
{
public:
virtual void DoIt() = 0;
};
Now we add a template for creating class-/method-specific derivatives:
template <class T>
class CTCommand : public CTCmdBase
{
private:
typedef void (T::*FnDoIt)();
T* pO;
FnDoIt pfnDoIt;
public:
virtual void DoIt() { (pO->*pfnDoIt)(); }
CTCommand(T* O, FnDoIt F)
: pO(O), pfnDoIt(F) {}
};
Now for the implementation;
class Echo_i : public virtual _sk_Echo {
public:
Echo_i() {}
virtual ~Echo_i() {}
virtual char * echoString(const char *mesg); //defined in idl
virtual void testit(); // not defined in idl
};
void Echo_i::testit() {
cerr << "Sleeping -----" << endl;
Sleep(10000);
}
void SpMWrapper(void* pCTparam) {
while(true) {
((CTCmdBase*)pCTparam)->DoIt();
}
}
int main(int argc, char **argv)
{
CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB2");
CORBA::BOA_ptr boa = orb->BOA_init(argc,argv,"omniORB2_BOA");
Echo_i *myobj = new Echo_i();
CTCommand<Echo_i> par(myobj, Echo_i::testit);
DWORD TID_TMOM;
HANDLE hThread_TMOM = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)SpMWrapper,
&par,
0,
(LPDWORD)&TID_TMOM
);
if(hThread_TMOM == NULL) {
cerr << "TMOM thread cannot be created\n";
}
}
This should do the job nicely, elegantly and typesafe.
Happy hunting,
Martin Corino.
> -----Original Message-----
> From: owner-omniorb-list@uk.research.att.com
> [mailto:owner-omniorb-list@uk.research.att.com]On Behalf Of Bing Zhang
> Sent: woensdag 10 maart 1999 20:52
> To: omniorb-list@uk.research.att.com
> Subject: [omniORB] Is this doable
>
>
> Hi,
>
> I modified a little bit of echo example to as following:
>
> class Echo_i : public virtual _sk_Echo {
> public:
> Echo_i() {}
> virtual ~Echo_i() {}
> virtual char * echoString(const char *mesg); //defined in idl
> virtual void testit(); // not defined in idl
> };
> void Echo_i::testit() {
> cerr << "Sleeping -----" << endl;
> Sleep(10000);
> }
>
> typedef void (Echo_i::*SpMType1)();
>
> struct CTstruct {
> SpMType M;
> Echo_i* O;
> };
>
> void SpMWrapper(void* pCTparam) {
> Echo_i* my_O = ((CTstruct*)pCTparam)->O;
> SpMType1 my_M = ((CTstruct*)pCTparam)->M;
>
> while(true) {
> (my_O->*my_M)();
> }
> }
>
> int main(int argc, char **argv)
> {
> CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB2");
> CORBA::BOA_ptr boa = orb->BOA_init(argc,argv,"omniORB2_BOA");
>
> struct CTstruct par;
> Echo_i *myobj = new Echo_i();
> par.O = myobj;
> par.M = Echo_i::testit;
> DWORD TID_TMOM;
> HANDLE hThread_TMOM = CreateThread(NULL,
> 0,
>
> (LPTHREAD_START_ROUTINE)SpMWrapper,
> &par,
> 0,
>
> (LPDWORD)&TID_TMOM
> );
> if(hThread_TMOM == NULL) {
> cerr << "TMOM thread cannot be created\n";
> }
> }
>
> Everything works fine. method testit() in future will be used to
> perodically update a CORBA object internal state.
>
> Now we want to enable the thread to run any CORBA object's member method (
> as long as the member method do not return anytion and take no
> parameters),
> we modify part of the code as
>
> typedef void (CORBA::Object::*SpMType)();
>
> struct CTstruct {
> SpMType M;
> CORBA::Object* O;
> };
>
> void SpMWrapper(void* pCTparam) {
> CORBA::Object* my_O = ((CTstruct*)pCTparam)->O;
> SpMType my_M = ((CTstruct*)pCTparam)->M;
>
> while(true) {
> (my_O->*my_M)();
> }
> }
>
> The main function is same. But the compiler complains the statement:
> par.M = Echo_i::testit;
> error C2440: '=' : cannot convert from 'void (Echo_i::*)(void)' to 'void
> (CORBA::Object::*)(void)'
> Types pointed to are unrelated;
> conversion requires reinterpret_cast, C-style cast or function-style cast
> Error executing cl.exe.
>
> How could we get around of this? If it is not possible, any other
> method so
> that we could achieve our goal?
>
> Thanks
>
> Bing
>
>
>
>
>
>