Archived

This topic is now archived and is closed to further replies.

Class Structure Question & Multithreading

This topic is 5309 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

The CreateThread()''s third parameter is a pointer to a function, but what happens if my function is within an instance of a class? Then what do I do? (I''ve tried EVERYTHING!) Second question, for my current networking project I have one main network class, a network recieving class, and a network sending class, and the main network class has instances of the sending and recieving classes. What is the best way to transfer data from the recieving class to the sending class? Thanks

Share this post


Link to post
Share on other sites
Your getting compile time errors saying the prototype does not match the definition.... Reason is that if you use an API and pass it a address of a class member you must make the member static. As a static definition does not hand the point (*this) to every member function. As they can be called as
Class::Name(args); Static by its definition means that it will not be seen outside of the current file. Also that if its a member it will share its values between threads. it is best to pass it the static member function but then pass it a structure as the void* to manipulate the state of the encapsulating class.

Downside is that static memeber functions can not access non static member functions.

Share this post


Link to post
Share on other sites
When using a member function in a class, a "hidden" argument is passed to the function. That argument is the "this" pointer, it tells the function which object it's being applied to (there can be more than one object of the same type).

The easy way to solve your problem is to make your function static (most likely private too)... If you want it to be associated with an object and plan to have multiple instances of the class, you can manage to pass your own "this" pointer (CreateThread allows to pass one argument). Passing your own "this" pointer will allow your static function to access the object its bound to.

About the second question... Its not too clear what you're asking... If its a protocol question, then that depends on your needs. In short, TCP is good for RTS games, UDP is good for action games.

[edited by - Max_Payne on June 4, 2003 2:16:55 PM]

Share this post


Link to post
Share on other sites
The member thread function would look like this:


class TestClass
{
public:
// This is what we want to run in a thread

void RunThread()
{
// Do whatever

}

// This is what we pass to create thread

static void* ThreadMethod(void *arg)
{
TestClass *pThis = reinterpret_cast<TestClass*>(arg);
pThis->RunThread();
return 0;
}
};

// Your create thread call would look something like this

TestClass instance;
CreateThread(..., TestClass::ThreadMethod, reinterpret_cast<void*>(&instance), ...)
// Or this... if done within the class

CreateThread(..., ThreadMethod, reinterpret_cast<void*>(this), ...);

Share this post


Link to post
Share on other sites
Maybe this helps, reusable thread class:

CThread.H

/*****************************************************************
* Author: Patrick van der Willik
* Date: April 23th 2003
* Revision: 1
* Comments: Thread wrapper
******************************************************************/

#ifndef _THREAD_H_
#define _THREAD_H_

#include <windows.h>

typedef void (*Thread_Func)(void *);
class CThread
{
public:
DWORD Create(Thread_Func, void *lpParam);
DWORD GetID();
void KillThread();
void WaitForFinish();
void Suspend();

private:
struct THREAD_DATA
{
Thread_Func ThreadFunc;
void *lpParams;
};

static DWORD WINAPI RealThread(LPVOID lpParams);
DWORD dwThreadID;
HANDLE hThread;
};

#endif


CThread.cpp

#include "CThread.h"

// Create new thread

DWORD CThread::Create(Thread_Func Thread, void *lpParam)
{
THREAD_DATA *Data = new THREAD_DATA;

if (!Data)
return (0);

// Fill in thread structure

Data->ThreadFunc = Thread;
Data->lpParams = lpParam;

// Create the thread

hThread = CreateThread(NULL, 0, CThread::RealThread, Data, 0, &dwThreadID);
if (hThread == NULL)
return (0);

return (dwThreadID);
}

// Get the Thread ID

DWORD CThread::GetID()
{
return (dwThreadID);
}

// Terminate the thread

void CThread::KillThread()
{
TerminateThread(hThread, 0);
CloseHandle(hThread);
}

// Suspend the thread

void CThread::Suspend()
{
Sleep(1);
}

// Wait until the thread ends and then close it''s handle

void CThread::WaitForFinish()
{
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}

// Real thread function. This function is started by the CreateThread function

// and executes the threads function.

DWORD CThread::RealThread(LPVOID lpParams)
{
THREAD_DATA *Data = (THREAD_DATA *)lpParams;

// Run thread function with the parameters;

Data->ThreadFunc(Data->lpParams);
delete Data;

return (0);
}


CMutex.H

/*****************************************************************
* Author: Patrick van der Willik
* Date: April 23th 2003
* Revision: 1
* Comments: Mutex Wrapper
******************************************************************/

#ifndef _MUTEX_H_
#define _MUTEX_H_

#include <windows.h>

class CMutex
{
public:
CMutex();
~CMutex();

void Lock();
void Unlock();

private:
CRITICAL_SECTION Mutex;
};

#endif


CMutex.cpp

#include "CMutex.h"

// Init the critical section

CMutex::CMutex()
{
InitializeCriticalSection(&Mutex);
}

// Clean up the critical section

CMutex::~CMutex()
{
DeleteCriticalSection(&Mutex);
}

// Lock the data by entering the critical section

void CMutex::Lock()
{
EnterCriticalSection(&Mutex);
}

// Unlock the data by leaving critical section

void CMutex::Unlock()
{
LeaveCriticalSection(&Mutex);
}


Usage is simple:

void Thread_Func(void *pParam)
{
// Thread code here
}

CThread Thread;
CMutex Mutex;

Thread.Create(Thread_Func, NULL); // Second is used for function parameters
Mutex.Lock(); // Lock data
// Altered thread shared data here
Mutex.Unlock(); // Unlock the data
Thread.KillThread();
[code]

Remember, the CMutex is the Critical Section, so you need to Lock() it before accessing shared data.

Toolmaker




-Earth is 98% full. Please delete anybody you can.

Share this post


Link to post
Share on other sites
You need to use _beginthreadex() instead of CreateThread in a class since _beginthreadex() initializes static structures used by the C runtime library for the new thread.

[edited by - antareus on June 5, 2003 7:40:33 PM]

Share this post


Link to post
Share on other sites