Jump to content
  • Advertisement
Sign in to follow this  
dave

Inheritance - Having base-class method call a derived method?

This topic is 4819 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok so im stuck on inheritance for some reason. The problem here is that the myservice class's methods OnInit() and OnRun() are not being called but the base classes ones are instead. servicebase.h
#ifndef		SERVICE_BASE_H
#define		SERVICE_BASE_H

#include	<string>
#include	<windows.h>

class		servicebase
{
public:
	servicebase( const std::string& serviceName );
	virtual ~servicebase();

	static		VOID	 WINAPI		OnStart( DWORD argc, LPTSTR* argv );
	virtual int							OnInit( DWORD argc,	 LPTSTR *argv );
	virtual int							OnRun( void );
	static		VOID	 WINAPI		ServiceControlHandler( DWORD code );

protected:
	SERVICE_TABLE_ENTRY			m_dispatchTable[2];
	SERVICE_STATUS					m_serviceStatus;
	SERVICE_STATUS_HANDLE		m_serviceStatusHandle;
	std::string								m_serviceName;

	static		servicebase*				m_pThis;


	int		InitDispatchTable();
	int		StartServiceControlDispatcher();
};


#endif




servicebase.cpp
#include	"windowsservicebase.h"

servicebase::servicebase( const std::string& processName )
:
m_serviceName( processName )
{
	m_pThis = this;
	if ( InitDispatchTable() != -1 )
	{
		StartServiceControlDispatcher();
	}

}

servicebase::~servicebase()
{
}

int		servicebase::InitDispatchTable()
{
	void*		pCopiedMem;

	SERVICE_TABLE_ENTRY	tempArray[] = { 
		{	(LPSTR) &m_serviceName[0], OnStart	},
		{	NULL, NULL	}
	};

	pCopiedMem = memcpy( m_dispatchTable, tempArray, 2 * sizeof( SERVICE_TABLE_ENTRY ) );

	if ( pCopiedMem !=  m_dispatchTable )
	{
		return -1;
	}
	return 0;
}

int		servicebase::StartServiceControlDispatcher()
{
	if ( StartServiceCtrlDispatcher( m_dispatchTable ) == false )
	{
		return -1;
	}
	return 0;
}

VOID WINAPI		servicebase::OnStart( DWORD argc, LPTSTR* argv )
{
	m_pThis->m_serviceStatus.dwServiceType						=	SERVICE_WIN32; 
    m_pThis->m_serviceStatus.dwCurrentState						=	SERVICE_START_PENDING; 
    m_pThis->m_serviceStatus.dwControlsAccepted				=	SERVICE_ACCEPT_STOP | 
																							SERVICE_ACCEPT_PAUSE_CONTINUE; 
    m_pThis->m_serviceStatus.dwWin32ExitCode					= 0; 
    m_pThis->m_serviceStatus.dwServiceSpecificExitCode		= 0; 
    m_pThis->m_serviceStatus.dwCheckPoint						= 0; 
    m_pThis->m_serviceStatus.dwWaitHint							= 0; 
 
    m_pThis->m_serviceStatusHandle	 = RegisterServiceCtrlHandler(	"MyService",
																										ServiceControlHandler); 
  
	m_pThis->OnInit( argc, argv );

    // Initialization complete - report running status. 
    m_pThis->m_serviceStatus.dwCurrentState			= SERVICE_RUNNING; 
    m_pThis->m_serviceStatus.dwCheckPoint			= 0; 
    m_pThis->m_serviceStatus.dwWaitHint				= 0; 
 
	SetServiceStatus (m_pThis->m_serviceStatusHandle, &(m_pThis->m_serviceStatus));

	m_pThis->OnRun();
}

VOID	 WINAPI	servicebase::ServiceControlHandler( DWORD code )
{
   switch(code) 
   { 
      case SERVICE_CONTROL_PAUSE: 
      // Do whatever it takes to pause here. 
         m_pThis->m_serviceStatus.dwCurrentState = SERVICE_PAUSED; 
         break; 
 
      case SERVICE_CONTROL_CONTINUE: 
      // Do whatever it takes to continue here. 
         m_pThis->m_serviceStatus.dwCurrentState = SERVICE_RUNNING; 
         break; 
 
      case SERVICE_CONTROL_STOP: 
      // Do whatever it takes to stop here. 
         m_pThis->m_serviceStatus.dwWin32ExitCode = 0; 
         m_pThis->m_serviceStatus.dwCurrentState  = SERVICE_STOPPED; 
         m_pThis->m_serviceStatus.dwCheckPoint    = 0; 
         m_pThis->m_serviceStatus.dwWaitHint      = 0; 

         if (!SetServiceStatus (m_pThis->m_serviceStatusHandle, 
           &(m_pThis->m_serviceStatus)))
         { 
         } 
         return; 
 
      case SERVICE_CONTROL_INTERROGATE: 
      // Fall through to send current status. 
         break; 
   } 
 
   // Send current status. 
   if (!SetServiceStatus (m_pThis->m_serviceStatusHandle,  &(m_pThis->m_serviceStatus))) 
   { 
   } 
}

int						servicebase::OnInit( DWORD argc,	 LPTSTR *argv )
{
	return 0;
}

int						servicebase::OnRun()
{
	return 0;
}

servicebase* servicebase::m_pThis;




myservice.h
#ifndef		MY_SERVICE_H
#define		MY_SERVICE_H

#include	"windowsservicebase.h"

#include <fstream>

class		myservice : public servicebase
{
public:
	myservice( const std::string& serviceName );
	~myservice();

	int		OnInit( DWORD argc, LPTSTR* argv );
	int		OnRun( void );
};

#endif




myservice.cpp
#include "myservice.h"

myservice::myservice( const std::string& serviceName )
:
servicebase( serviceName )
{
	
}

myservice::~myservice()
{
}

int myservice::OnInit( DWORD argc, LPTSTR* argv )
{
	std::ofstream out;

	out.open("c:\\out.txt", std::ofstream::out );

	out << "hello";

	out.close();
	return 0;
}

int myservice::OnRun()
{
	return 0;
}



I have tried removing the servicebase::OnInit() and OnRun() methods implementation and leaving it as pure virtual but when the exe was executing i seemed to be getting an error saying that i was calling a virtual function or something. Can anyone tell me where im going wrong? Thanks ace

Share this post


Link to post
Share on other sites
Advertisement
Ok so i realised what the problem is.

The servicebase::OnStart() method calls the base-class virtual method because it doen't know of the derrived one.

So is there an easy work around to make the baseclass::OnStart() call a derrived myclass::OnInit().

ace

Share this post


Link to post
Share on other sites
Your problem seems to be that you're trying to call OnStart() while still within the scope of the constructor of your base class. This doesn't work because at that point your object isn't of the same type as your derived class yet. It's still of type of the base class. Try delaying the call until after the derived class is constructed.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!