Hi ALL
I am Srinivasan S Saripalli. I have a VC++ doubt which I have notified below. Hope you can give me a solution.

I have developed a ATL,COM 32-bit Service and in the Service I am implementing Timer functionality using either SetWaitableTimer or CreateWaitableTimer. When I compile my Service App I get the error as shown below

The ATL Win32 Service wizard generates a class mentioned below

class CServiceModule : public CComModule
{


public:


------------------------------------


------------------------------------


// here I have declared my Timer callback function to be


VOID CALLBACK TimerAPCProc(LPVOID lpArg,DWORD dwTimerLowValue,DWORD dwTimerHighValue);
HANDLE gDoneEvent;


};


In the implementation file ( *.cpp ) my code is shown below


#define _SECOND 10000000
typedef struct _MYDATA {
TCHAR *szText;
DWORD dwValue;
} MYDATA;
VOID CALLBACK CServiceModule::TimerAPCProc(
LPVOID lpArg,               // Data value
DWORD dwTimerLowValue,      // Timer low value
DWORD dwTimerHighValue )    // Timer high value


{
MYDATA *pMyData = (MYDATA *)lpArg;


/*_tprintf( TEXT("Message: %s\nValue: %d\n\n"), pMyData->szText,
pMyData->dwValue );
MessageBeep(0);*/


}


I have added the Timer functionality in the Run() method of the class CServiceModule


if (m_bService)
{
HANDLE          hTimer;
BOOL            bSuccess;
__int64         qwDueTime;
LARGE_INTEGER   liDueTime;
MYDATA          MyData;


MyData.szText = TEXT("This is my data");
MyData.dwValue = 100;


hTimer = CreateWaitableTimer(
NULL,                   // Default security attributes
FALSE,                  // Create auto-reset timer
TEXT("MyTimer"));       // Name of waitable timer


if (hTimer != NULL)
{
// Create an integer that will be used to signal the timer
// 5 seconds from now.
qwDueTime = -5 * _SECOND;


// Copy the relative time into a LARGE_INTEGER.
liDueTime.LowPart  = (DWORD) ( qwDueTime & 0xFFFFFFFF );
liDueTime.HighPart = (LONG)  ( qwDueTime >> 32 );


bSuccess = SetWaitableTimer(
hTimer,           // Handle to the timer object
&liDueTime,       // When timer will become signaled
2000,             // Periodic timer interval of 2 seconds
TimerAPCProc,     // Completion routine
&MyData,          // Argument to the completion routine
FALSE );


if ( bSuccess )
{
for ( ; MyData.dwValue < 1000; MyData.dwValue += 100 )
{
SleepEx(
INFINITE,     // Wait forever
TRUE );       // Put thread in an alertable state
}


}
else
{
printf("SetWaitableTimer failed with error %d\n",
GetLastError());
}
CloseHandle(hTimer);


}
else
{
printf("CreateWaitableTimer failed with error %d\n",
GetLastError());
}

When I compile this application I get the error as shown below

C:\srini\adminservice\SinumerikTimerService\SinumerikTimerService.cpp(398) : error C2664: 'SetWaitableTimer' : cannot convert parameter 4 from 'void (void *,unsigned long,unsigned long)' to 'void (__stdcall *)(void *,unsigned long,unsigned long)'

None of the functions with this name in scope match the target type
Error executing cl.exe.

Searching at Google and a person tells me that I should replace CALLBACK with __stdcall but why should I do that because CALLBACK in <winbase.h> is #define CALLBACK __stdcall but still I changed CALLBACK to __stdcall and also typecasted TimerAPCProc to be (PTIMERAPCROUTINE)TimerAPCProc but still I get the same error with respect to SetWaitableTimer

I have also #defined _WIN32_WINNT macro to be 0x0500 but still the error comes.

Also I have installed WinXP SP2 Platform SDK, Visual Studio 2005.

Therefore, I have added the path "C:\PROGRAM FILES\MICROSOFT PLATFORM SDK FOR WINDOWS XP SP2\INCLUDE" in Tools--> Options --> Directories and this gives me one more error

msxml.idl
C:\PROGRAM FILES\MICROSOFT PLATFORM SDK FOR WINDOWS XP SP2\INCLUDE\msxml.idl(52) : fatal error C1083: Cannot open include file: 'xmldom.idl': No such file or directory
midl : command line error MIDL1003 : error returned by the C preprocessor (2)
Error executing midl.exe.

To resolve the above xmldom.idl error I came to know that I have to install latest platform SDK.

However If I include "C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO 8\VC\PLATFORMSDK\INCLUDE" then the above xmldom.idl gets resolved and I get the below actual error

C:\srini\adminservice\SinumerikTimerService\SinumerikTimerService.cpp(398) : error C2664: 'SetWaitableTimer' : cannot convert parameter 4 from 'void (void *,unsigned long,unsigned long)' to 'void (__stdcall *)(void *,unsigned long,unsigned long)'
None of the functions with this name in scope match the target type
Error executing cl.exe.

I would be thankful to everybody who can give me a effective solution to the above problem.

Regards,

Srinivasan

Implement the timer proc outside the CServiceModule class.
I.e. you will have

VOID CALLBACK ::TimerAPCProc(...)

instead of

VOID CALLBACK CServiceModule::TimerAPCProc(...)
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.