SDL_CreateThread with C++ method as a parameter

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 matchint ()(void)”

Searching with Google didn’t helped me:
static int Tetra::StaticThreadProcGravity(void* pParam)
{
return ((Tetra*)pParam)->ThreadGravity();
}

I still get an error.

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 matchint ()(void)”

You can’t pass in a C++ member function directly because the signature won’t match. Remember, a non-static C++ member function will take “this” as an implicit argument.

static int Tetra::StaticThreadProcGravity(void* pParam)
[…]
I still get an error.

You don’t show exactly what you did and what the error was so I can’t help you. Passing in a static member function should work.

See if this helps:
http://www.newty.de/fpt/callback.html#staticOn Sat, 22 Mar 2008 13:46:52 +0100, PS3-690 wrote:

The following compiles and runs for me:

class Tetra {
public:
void runThread()
{
SDL_Thread *thread = SDL_CreateThread(&StaticThreadProcGravity,this);
int ret;
SDL_WaitThread(thread,&ret);
std::cout << "thread ended with status " << ret << ‘\n’;
}

int ThreadGravity() { return 0; }

static int StaticThreadProcGravity(void* pParam)
{
return ((Tetra*)pParam)->ThreadGravity();
}
};

Is there anything that you are doing differently (apart from the body
of the thread function itself).On Sat, Mar 22, 2008 at 12:46 PM, PS3-690 wrote:

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 matchint ()(void)”

Searching with Google didn’t helped me:
static int Tetra::StaticThreadProcGravity(void* pParam)
{
return ((Tetra*)pParam)->ThreadGravity();
}

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 matchint ()(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

2008/3/22, Brian <brian.ripoff at gmail.com>:

The following compiles and runs for me:

class Tetra {
public:
void runThread()
{
SDL_Thread *thread =
SDL_CreateThread(&StaticThreadProcGravity,this);
int ret;
SDL_WaitThread(thread,&ret);
std::cout << "thread ended with status " << ret << ‘\n’;
}

int ThreadGravity() { return 0; }

static int StaticThreadProcGravity(void* pParam)
{
return ((Tetra*)pParam)->ThreadGravity();
}
};

Is there anything that you are doing differently (apart from the body
of the thread function itself).

no, its the same, but i still get errors like “invalid use of struct
SDL_Thread”

Searching with Google didn’t helped me:
static int Tetra::StaticThreadProcGravity(void* pParam)
{
return ((Tetra*)pParam)->ThreadGravity();
}

You have to declare it static in the class declaration.

class Tetra
{
blah blah whatever;
static int StaticThreadProcGravity(void* pParam);
};

int Tetra::StaticThreadProcGravity(void* pParam)
{
code goes here;
}

Otherwise, the method will expect a “this pointer” to be quietly passed
to it, which would confuse things, and the compiler catches this.

–ryan.

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. :frowning:
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 matchint ()(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

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 matchint ()(void)”

See the C++ FAQ at parashift.com, the problem is the difference between a
(free) function and a memberfunction.

static int Tetra::StaticThreadProcGravity(void* pParam)
{
return ((Tetra*)pParam)->ThreadGravity();
}

Please, never use C-style casts in C++. Use static_cast here.

UliOn Saturday 22 March 2008 13:46:52 PS3-690 wrote:

Since I can’t solute the problem, I’ll use a another library for threads.

^^^^^^^^^^^^^^^^^^^^^^^^

This needs to be

&Tetra::StaticThreadProcGraviti

i.e. the full qualification with ‘Tetra::’ is required, just like the
address-of operator. Yes, there are compilers that don’t check this
requirement, but most modern ones do.

UliOn Saturday 22 March 2008 14:51:17 Brian wrote:

class Tetra {
public:
void runThread()
{
SDL_Thread *thread =SDL_CreateThread(&StaticThreadProcGravity,this);

Hi,

I’m curious to know if you’re coming to SDL/C++ from Java.

I was taught OO-programming with Java and it would seem that you’re
hitting some of the same conceptual stumbling blocks I came across when
I started to do non-trivial programming in C++…On the assumption that you ARE coming at it from Java, I have some thoughts that may help you: C++ isn’t Java, that is, the object models in Java and C++ are different. Java’s object model is more ‘pure’ that C++‘s, but that comes at a HUGE cost (i.e. computational overhead and about 2x the memory requirements). This is difference in object models is especially true when you start mixing C++ and C. It’s not nice, it’s not pretty (C++ is probably the worst language aesthetically - after VB LOL), but it’s cheap - ie, you get what you get with as little overhead as possible… and you don’t get a compiler that thinks it’s cleverer than you (my #1 gripe with Java…). Just to stick up for SDL: I think that you’ll find that all the threading libraries out their do more-or-less the same things, in the same ways. This is because 99% of them are C-based (because it’s generally more cross-platform than C++) and the theory behind threading is pretty well understood - there are only so many ways of managing threads. Incidentally, the SDL Threads API is VERY neat and tidy at about 20 funcs, compared to the Pthreads (OS-level) API which is about 5 times larger! So, essentially, the problem here is in the way C and C++ interact, rather than with the fundamental design of the SDL APIs (not that I’m saying they can’t be improved). Every C++ programmer I’ve ever talked about has raved about Myers’ “Effective C++” and I have to agree. I personally found Stroustrup’s own “The C++ Programming Language” very informative too. Get them out of the library and re-visit the problem. Eddy PS3-690 wrote:

Since I can’t solute the problem, I’ll use a another library for threads.



SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org