[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
>
>
>
>
>
>