The function pointer you are passing to SDL_CreateThread is technically of
type int (Tetra::)(void) in C++ typing system, whereas SDL_CreateThread is
expecting a function pointer of type int ()(void); the notation used for
function pointer types in C++ is confusing and difficult to read.
What you will have to do is make a function of the correct type, which would
be a namespace scope function with the following signature: int
func(void*);
This shouldn’t be too hard in your case since you were already passing in
what would appear to be the equivalent of a this pointer into a static class
member function. Unfortunately, more elegant solutions delve into the real
of advanced C++ programming idioms: specifically, templated functors and a
Singleton. The best way to handle this that I can come up with is the
following:
Make a namespace function that takes a void* pointer which is used to
represent the function id. Inside the function, invoke a call to a
Singleton manager class and give it the function id; the manager class maps
the id to a function that was registered with it before hand and invokes
that function. The biggest disadvantage to this is that Singleton’s are not
thread-safe by default, and making them thread-safe can be quite painful.
You would also probably want to wrap the function pointers with a Functor
type; the Loki::Functor class works quite well for this, but the code is not
for the faint of heart. The other disadvantage is that if you use the void*
pointer for the function id, you’ve lost your ability to pass a parameter to
the thread function. Loki is at http://loki-lib.sourceforge.net and
http://moderncppdesign.com If you use Loki, you would probably end up with
something like:
// ThreadFunctionManager.h
class ThreadFunctionManager_t
{
public:
typedef Loki::Functor ThreadFunctor;
/// The ID type and generation method is up to you; I’m using integers
for simplicity’s sake.
typedef uint32_t IdType;
IdType registerFunction(const ThreadFunctor& func)
{
// Lock the thread to prevent synchronization issues.
mLock->acquire();
// generate a function id somehow; worst case scenario would be a
thread safe deque that increments a counter.
IdType id = generateId();
mFunctorMap[id] = func;
mLock->release();
return id;
}
int invokeFunction(const IdType& id)
{
if (mFunctorMap.find(id) != mFunctorMap.end())
{
return mFunctorMap[id]();
}
}
private:
/// Function id to Thread Function map
std::map<IdType, ThreadFunctor> mFunctorMap;
/// Thread Mutex; create this whichever way works best with your app.
Mutex mLock;
};
typedef Loki::SingletonHolder<ThreadFunctionManager_t>
ThreadFunctionManager;
int invokeThreadFunction(void* functionId)
{
return
ThreadFunctionManager::Instance().invokeFunction((reinterpret_cast<IdType>(functionId)));
}
To use this, you would have to register each function you might want to use
as a separate thread with:
// Somefile.cpp
…
IdType function_id =
ThreadFunctionManager::Instance().registerFunction(myfunc);
…
And then to create a thread with a specific function that’s been registered,
just call:
// Somefile.cpp
…
SDL_CreateThread(invokeThreadFunction,
reinterpret_cast<void*>(&functionId));
…
And it should all work. One thing to note is that the Singleton’s
Instance() method may have to be made thread-safe if you invoke it from
separate threads; Loki has built-in mechanisms to do this. Hopefully this
was more helpful that it was confusing; please don’t hesitate to ask if you
have any questions.
Regards,
Johnathan GurleyOn Sat, Mar 22, 2008 at 8:55 AM, Guilherme Farrer wrote:
2008/3/22, PS3-690 :
Hello,
I have a problem with SDL_CreateThread. I want to use it with a C++
method:
SDL_CreateThread(function, NULL);
But then I get an Error:
“argument of type int (Class::)(void*)' does not match
int ()(void)”
The problem is that the C++ pointer to a class member function is
different from a pointer to a C function (and SDL_CreateThread expects
a C function). To fix this, create the thread with a C function (not
to a C++ one).
Searching with Google didn’t helped me:
static int Tetra::StaticThreadProcGravity(void* pParam)
{
return ((Tetra*)pParam)->ThreadGravity();
}
I still get an error.
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org