Thread: calling CreateThread from within a class

  1. #1
    Registered User
    Join Date
    Nov 2002
    Posts
    319

    calling CreateThread from within a class

    if DWORD WINAPI ListenThread(LPVOID Param) is a member function of gameListen class, how you you call CreateThread within the class?,

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You need a couple of things.

    The actual top-level thread function should be a static member function. Such functions do not automatically receive a īthisī pointer, so you need to construct one yourself. Fortunately, this arrives conveniently as the void* parameter of the thread function.

    Code:
    void tf ( void *p ) {
      myclass *cp = p; // use a proper c++ style cast
      cp->properThreadMethod();  // this will get a proper īthisī pointer
    }
    You invoke CreateThread with the above as the thread function, and īthisī as the void* parameter.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If you are looking for a C++ specific alternative for CreateThread, you should check out boost.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    What about C++0x std::threads? IDK about others, but GCC has an implementation of TR1.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    std::thread isn't part of TR1.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    Oops, I guess I was referring to GNU threads. Here's the file:
    (I tried to attach it, but it said it's invalid.)
    Code:
    // <thread> -*- C++ -*-
    
    // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
    //
    // This file is part of the GNU ISO C++ Library.  This library is free
    // software; you can redistribute it and/or modify it under the
    // terms of the GNU General Public License as published by the
    // Free Software Foundation; either version 3, or (at your option)
    // any later version.
    
    // This library is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    
    // Under Section 7 of GPL version 3, you are granted additional
    // permissions described in the GCC Runtime Library Exception, version
    // 3.1, as published by the Free Software Foundation.
    
    // You should have received a copy of the GNU General Public License and
    // a copy of the GCC Runtime Library Exception along with this program;
    // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    // <http://www.gnu.org/licenses/>.
    
    /** @file thread
     *  This is a Standard C++ Library header. True?
     */
    
    #ifndef _GLIBCXX_THREAD
    #define _GLIBCXX_THREAD 1
    
    #pragma GCC system_header
    
    #ifndef __GXX_EXPERIMENTAL_CXX0X__
    # include <c++0x_warning.h>
    #else
    
    #include <chrono>
    #include <functional>
    #include <memory>
    #include <mutex>
    #include <condition_variable>
    #include <cstddef>
    #include <bits/functexcept.h>
    #include <bits/gthr.h>
    
    #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
    
    namespace std
    {
      /**
       * @defgroup threads Threads
       * @ingroup concurrency
       *
       * Classes for thread support.
       * @{
       */
    
      /// thread
      class thread
      {
      public:
        typedef __gthread_t			native_handle_type;
        struct _Impl_base;
        typedef shared_ptr<_Impl_base>	__shared_base_type;
    
        /// thread::id
        class id
        {
          native_handle_type	_M_thread;
    
        public:
          id() : _M_thread() { }
    
          explicit
          id(native_handle_type __id) : _M_thread(__id) { }
    
        private:
          friend class thread;
    
          friend bool
          operator==(thread::id __x, thread::id __y)
          { return __gthread_equal(__x._M_thread, __y._M_thread); }
    
          friend bool
          operator<(thread::id __x, thread::id __y)
          { return __x._M_thread < __y._M_thread; }
    
          template<class _CharT, class _Traits>
    	friend basic_ostream<_CharT, _Traits>&
    	operator<<(basic_ostream<_CharT, _Traits>&& __out, thread::id __id);
        };
    
        // Simple base type that the templatized, derived class containing
        // an arbitrary functor can be converted to and called.
        struct _Impl_base
        {
          __shared_base_type	_M_this_ptr;
    
          virtual ~_Impl_base() = default;
    
          virtual void _M_run() = 0;
        };
    
        template<typename _Callable>
          struct _Impl : public _Impl_base
          {
    	_Callable		_M_func;
    
    	_Impl(_Callable&& __f) : _M_func(std::forward<_Callable>(__f))
    	{ }
    
    	void
    	_M_run() { _M_func(); }
          };
    
      private:
        id				_M_id;
    
      public:
        thread() = default;
        thread(const thread&) = delete;
    
        thread(thread&& __t)
        { swap(__t); }
    
        template<typename _Callable>
          explicit thread(_Callable __f)
          { _M_start_thread(_M_make_routine<_Callable>(__f)); }
    
        template<typename _Callable, typename... _Args>
          thread(_Callable&& __f, _Args&&... __args)
          { _M_start_thread(_M_make_routine(std::bind(__f, __args...))); }
    
        ~thread()
        {
          if (joinable())
    	std::terminate();
        }
    
        thread& operator=(const thread&) = delete;
    
        thread& operator=(thread&& __t)
        {
          if (joinable())
    	std::terminate();
          swap(__t);
          return *this;
        }
    
        void
        swap(thread&& __t)
        { std::swap(_M_id, __t._M_id); }
    
        bool
        joinable() const
        { return !(_M_id == id()); }
    
        void
        join();
    
        void
        detach();
    
        thread::id
        get_id() const
        { return _M_id; }
    
        /** @pre thread is joinable
         */
        native_handle_type
        native_handle()
        { return _M_id._M_thread; }
    
        // Returns a value that hints at the number of hardware thread contexts.
        static unsigned int
        hardware_concurrency()
        { return 0; }
    
      private:
        void
        _M_start_thread(__shared_base_type);
    
        template<typename _Callable>
          shared_ptr<_Impl<_Callable>>
          _M_make_routine(_Callable&& __f)
          {
    	// Create and allocate full data structure, not base.
    	return make_shared<_Impl<_Callable>>(std::forward<_Callable>(__f));
          }
      };
    
      inline void
      swap(thread& __x, thread& __y)
      { __x.swap(__y); }
    
      inline void
      swap(thread&& __x, thread& __y)
      { __x.swap(__y); }
    
      inline void
      swap(thread& __x, thread&& __y)
      { __x.swap(__y); }
    
      inline bool
      operator!=(thread::id __x, thread::id __y)
      { return !(__x == __y); }
    
      inline bool
      operator<=(thread::id __x, thread::id __y)
      { return !(__y < __x); }
    
      inline bool
      operator>(thread::id __x, thread::id __y)
      { return __y < __x; }
    
      inline bool
      operator>=(thread::id __x, thread::id __y)
      { return !(__x < __y); }
    
      template<class _CharT, class _Traits>
        inline basic_ostream<_CharT, _Traits>&
        operator<<(basic_ostream<_CharT, _Traits>&& __out, thread::id __id)
        {
          if (__id == thread::id())
    	return __out << "thread::id of a non-executing thread";
          else
    	return __out << __id._M_thread;
        }
    
      /** @namespace std::this_thread
       *  @brief ISO C++ 0x entities sub namespace for thread.
       *  30.2.2 Namespace this_thread.
       */
      namespace this_thread
      {
        /// get_id
        inline thread::id
        get_id() { return thread::id(__gthread_self()); }
    
    #ifdef _GLIBCXX_USE_SCHED_YIELD
        /// yield
        inline void
        yield()
        { __gthread_yield(); }
    #endif
    
    #ifdef _GLIBCXX_USE_NANOSLEEP
        /// sleep_until
        template<typename _Clock, typename _Duration>
          inline void
          sleep_until(const chrono::time_point<_Clock, _Duration>& __atime)
          { sleep_for(__atime - _Clock::now()); }
    
        /// sleep_for
        template<typename _Rep, typename _Period>
          inline void
          sleep_for(const chrono::duration<_Rep, _Period>& __rtime)
          {
    	chrono::seconds __s =
    	  chrono::duration_cast<chrono::seconds>(__rtime);
    
    	chrono::nanoseconds __ns =
    	  chrono::duration_cast<chrono::nanoseconds>(__rtime - __s);
    
    	__gthread_time_t __ts =
    	  {
    	    static_cast<std::time_t>(__s.count()),
    	    static_cast<long>(__ns.count())
    	  };
    
    	::nanosleep(&__ts, 0);
          }
    #endif
      }
    
      // @} group threads
    }
    
    #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
    
    #endif // __GXX_EXPERIMENTAL_CXX0X__
    
    #endif // _GLIBCXX_THREAD

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It's part of C++0x, though. GCC may be the only one that has implemented it.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Calling a class member through a pointer to a class in a DLL
    By cboard_member in forum C++ Programming
    Replies: 1
    Last Post: 04-19-2006, 10:55 AM
  2. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  3. Calling class member
    By prog-bman in forum C++ Programming
    Replies: 14
    Last Post: 07-18-2004, 12:23 PM
  4. Calling a Function From A Class
    By Okiesmokie in forum C++ Programming
    Replies: 8
    Last Post: 06-28-2002, 10:09 PM