CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Apr 2009
    Posts
    1,355

    [RESOLVED] how call a procedure, like a new thread, with parameters?

    heres my timer class(isn't a good thing, but works lol):
    Code:
    #include <Windows.h>
    
    //for create a timer
    class Timer
    {
    	private: 
    		int MilliSecondsTimer;
    	private:
    		bool blnDestroyed;
    	private:
    		HANDLE Handle_Of_Thread_1;
    		typedef void (*MyTimerProc)();
    		MyTimerProc TimerProcedure;
    		static DWORD WINAPI StaticThreadProc(LPVOID param) 
    		{
    			static_cast<Timer*>(param)->MultithreadProcedure();
    			return 0;
    		}
    	public: 
    		int SetMilliSeconds(int MilliSeconds)
    		{
    			MilliSecondsTimer = MilliSeconds;
    			return 0;
    		}
    	public: 
    		int GetMilliSeconds()
    		{
    			return (MilliSecondsTimer);
    		}
    	private: void   MultithreadProcedure() 
    		{
    			for (;;) 
    			{
    				if (blnDestroyed==true) break;
    				Sleep(MilliSecondsTimer);
    				TimerProcedure();
    			}
    			CloseHandle(Handle_Of_Thread_1);
    			TerminateThread( Handle_Of_Thread_1,1);
    		}
    	public:
    		int Start(MyTimerProc TimerProc(...)) 
    		{
    			TimerProcedure = TimerProc();
    			Handle_Of_Thread_1=0;
    			CloseHandle(Handle_Of_Thread_1);
    			TerminateThread( Handle_Of_Thread_1,1);
    			blnDestroyed=false;
    			HANDLE hMyThread;
    			hMyThread = CreateThread(NULL, 0, StaticThreadProc, this, 0, NULL);
    			return 0;
    		}
    	public: int Stop()
    		{
    			blnDestroyed=true;			
    			return 0;
    		}
    		~Timer()
    		{
    			Stop();
    		}
    };
    imagine that the sub have some arguments, how can use them, when i call the sub?

    see these sample:

    Code:
    Timer c;	c.SetMilliSeconds(100);
    	c.Start( SetTextXY(10,10,"hello",100,500));
    error message:
    "IntelliSense: argument of type "void" is incompatible with parameter of type "Timer::MyTimerProc (*)(...)""
    any advice?

  2. #2
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: how call a procedure, like a new thread, with parameters?

    How many times will we have to say you again and again that these two lines of code:
    Quote Originally Posted by Cambalinho View Post
    heres my timer class(isn't a good thing, but works lol):
    Code:
    			CloseHandle(Handle_Of_Thread_1);
    			TerminateThread( Handle_Of_Thread_1,1);
    1. will never work as you expect
    2. are wrong because thread won't terminate that way
    3. using TerminateThread is wrong by default

    So, please, fix this issue first.
    Second, please do NOT put more than one statement in the same line. And do NOT compare boolean with true. So instead of
    Quote Originally Posted by Cambalinho View Post
    Code:
    if (blnDestroyed==true) break;
    please, write
    Code:
    if (blnDestroyed) 
    	break;
    Victor Nijegorodov

  3. #3
    Join Date
    Apr 2009
    Posts
    1,355

    Re: how call a procedure, like a new thread, with parameters?

    Quote Originally Posted by VictorN View Post
    How many times will we have to say you again and again that these two lines of code:
    1. will never work as you expect
    2. are wrong because thread won't terminate that way
    3. using TerminateThread is wrong by default

    So, please, fix this issue first.
    Second, please do NOT put more than one statement in the same line. And do NOT compare boolean with true. So instead of please, write
    Code:
    if (blnDestroyed) 
    	break;
    ok... i change the code for user real timers
    Code:
    #include <Windows.h>
    
    //for create a timer
    class Timer
    {
    	private: 
    		int MilliSecondsTimer;
    	private:
    		bool blnDestroyed;
    		UINT TimerId;
    	private:
    		HANDLE Timer1;
    		typedef void (*MyTimerProc)();
    		MyTimerProc TimerProcedure;
    		static DWORD WINAPI StaticThreadProc(LPVOID param) 
    		{
    			static_cast<Timer*>(param)->MultithreadProcedure(); //heres another error in last ')'
    			return 0;
    		}
    	public: 
    		int SetMilliSeconds(int MilliSeconds)
    		{
    			MilliSecondsTimer = MilliSeconds;
    			return 0;
    		}
    	public: 
    		int GetMilliSeconds()
    		{
    			return (MilliSecondsTimer);
    		}
    	private: void CALLBACK MultithreadProcedure(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
    		{				
    			TimerProcedure();			
    		}
    	public:
    		int Start(MyTimerProc TimerProc) 
    		{
    			TimerProcedure=TimerProc;
    			TimerId = SetTimer(NULL, 0, MilliSecondsTimer,&MultithreadProcedure); // the '&' is give me an error
    			return 0;
    		}
    	public: int Stop()
    		{
    			KillTimer( NULL,TimerId);			
    			return 0;
    		}
    		~Timer()
    		{
    			Stop();
    		}
    };
    errors messages:
    1 - "Error C2660: 'Timer::MultithreadProcedure' : function does not take 0 arguments";
    2 - "Error C2276: '&' : illegal operation on bound member function expression";
    3 - "IntelliSense: too few arguments in function call";
    4 - "IntelliSense: argument of type "void (__stdcall Timer::*)(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)" is incompatible with parameter of type "TIMERPROC"".

    any advice?

  4. #4
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: how call a procedure, like a new thread, with parameters?

    Quote Originally Posted by Cambalinho View Post
    errors messages:
    1 - "Error C2660: 'Timer::MultithreadProcedure' : function does not take 0 arguments";
    2 - "Error C2276: '&' : illegal operation on bound member function expression";
    ...

    any advice?
    What "advice"?
    1. Compiler states very clear that 'Timer::MultithreadProcedure' method requires non=yero number of parameters! Please look at this method declaration.
    2. See http://msdn.microsoft.com/en-us/library/850cstw1.aspx and other discussions in https://www.google.com/search?source...sion&gs_htsa=1
    Victor Nijegorodov

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: how call a procedure, like a new thread, with parameters?

    static_cast<Timer*>(param)->MultithreadProcedure();
    calls MultithreadProcedure with no arguments

    void CALLBACK MultithreadProcedure(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
    definition requires 4 parameters!
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  6. #6
    Join Date
    Apr 2009
    Posts
    1,355

    Re: how call a procedure, like a new thread, with parameters?

    finally heres a nice multithread code and adding arguments to it:
    Code:
    //Multithread with arguments
    //these struture is for add the arguments
    struct SetText
    {
    	int PosX;
    	int PosY;
    	char *Text;
    
    };
    
    //these is the argument sub
    unsigned int __stdcall SetTextXY(void *params) 
    {
        SetText *p = static_cast<SetText *>(params);
        // now you can take the value from p, for example
        
        int len = strlen(p->Text); 
        COORD ord;
        ord.X = p->PosX ;
        ord.Y = p->PosY ;	
        
        char *a = new char[len + 1];
        memset(a, 32, len);
        a[len] = '\0';
     
       
            SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), ord);
            std::cout << a;
            Sleep(500);
            SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), ord);
            std::cout << p->Text;
           Sleep(500);		
           return 0;
       
    }
    /* run this program using the console pauser or add your own getch, system("pause") or input loop */
    
    int main(int argc, char** argv) 
    {
    	
    	//the arguments struture
    	SetText *x=new SetText;
    	x->PosX=5;
    	x->PosX=6;
    	x->Text ="hello mother";
    	int  c =10;	
    	_beginthreadex(NULL, 0, SetTextXY, x, 0, NULL);	 	
    	return 0;
    }
    very cool ha?

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: how call a procedure, like a new thread, with parameters?

    Quote Originally Posted by Cambalinho View Post
    very cool ha?
    No.
    Code:
    unsigned int __stdcall SetTextXY(void *params) 
    {
        SetText *p = static_cast<SetText *>(params);
        int len = strlen(p->Text);
    If p is NULL, the code crashes.
    Code:
        char *a = new char[len + 1];
        memset(a, 32, len);
        a[len] = '\0';
    No call to delete[] to deallocate the memory, thus you have a memory leak. What's wrong with using a string class instead of this call to new[]?
    finally heres a nice multithread code and adding arguments to it:
    And lastly, when you create a real multithread program, it takes much more than calling begintreadex. Multithreaded programming is a highly technical topic and requires months if not years of experience to understand fully, debug, maintain, etc. You are not going to learn it by calling beginthreadex, you have to learn the various synchronization objects (mutex, semaphore, etc.), when, where, and how to use them, how to debug if there is a "race condition" or other multithreaded problem, etc.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; August 23rd, 2013 at 10:50 PM.

  8. #8
    Join Date
    Apr 2009
    Posts
    1,355

    Re: how call a procedure, like a new thread, with parameters?

    Quote Originally Posted by Paul McKenzie View Post
    No.
    Code:
    unsigned int __stdcall SetTextXY(void *params) 
    {
        SetText *p = static_cast<SetText *>(params);
        int len = strlen(p->Text);
    If p is NULL, the code crashes.
    Code:
        char *a = new char[len + 1];
        memset(a, 32, len);
        a[len] = '\0';
    No call to delete[] to deallocate the memory, thus you have a memory leak. What's wrong with using a string class instead of this call to new[]?

    And lastly, when you create a real multithread program, it takes much more than calling begintreadex. Multithreaded programming is a highly technical topic and requires months if not years of experience to understand fully, debug, maintain, etc. You are not going to learn it by calling beginthreadex, you have to learn the various synchronization objects (mutex, semaphore, etc.), when, where, and how to use them, how to debug if there is a "race condition" or other multithreaded problem, etc.

    Regards,

    Paul McKenzie
    thanks for all my friend

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured