multithreading and member-functions

I

Ilia Poliakov

Can I run a thread with _beginthread() and pass as the first parameter the
pointer on a member function of a class?

#include <process.h>

class A
{
void _cdecl f(void*) {};
};

void main()
{
_beginthread(&A::f, 0, NULL);
}

I get the compilation error:
error C2664: '_beginthread' : Konvertierung des Parameters 1 von 'void
(__cdecl A::* )(void *)' in 'void (__cdecl *)(void *)' nicht moglich

PS. I work in MSVC7.0 (german version :), console application
 
J

Josephine Schafer

Ilia Poliakov said:
Can I run a thread with _beginthread() and pass as the first parameter the
pointer on a member function of a class?

#include <process.h>

class A
{
void _cdecl f(void*) {};
};

void main()
{
_beginthread(&A::f, 0, NULL);
}

I get the compilation error:
error C2664: '_beginthread' : Konvertierung des Parameters 1 von 'void
(__cdecl A::* )(void *)' in 'void (__cdecl *)(void *)' nicht moglich

PS. I work in MSVC7.0 (german version :), console application

1. It would be better if you ask this on a Windows NG.
2. Please translate the errors to English whenever posting.
Then may be someone here can help you.
 
A

Attila Feher

Ilia said:
Can I run a thread with _beginthread() and pass as the first
parameter the pointer on a member function of a class?

Nope. AFAIK _beginthread is a C function, taking a void * argument.
Pointers and pointers to members are very different beasts. A pointer to a
member (function or variable) can have a very different implementation than
a normal pointer. The standard (let me not look it up) clearly states that
such conversion (from and to) is not supported. IMHO the best you can do is
to make a little class containing that pointer to member, create it (either
static/global, dynamicly allocated or some other way that ensures that it is
still there when the new thread tries to access it) and pass a pointer to
this very "argument list" to the new thread. Of course if you need more
arguments you can add them into this class (or struct).
 
I

Ilia Poliakov

1. It would be better if you ask this on a Windows NG.

_beginthread() is a C run-time function and has no relationship to any OS.
2. Please translate the errors to English whenever posting.
Then may be someone here can help you.

error C2664: '_beginthread' : convertion of parameter 1 from 'void (__cdecl
A::* )(void *)' in 'void (__cdecl *)(void *)' not possible
 
A

Attila Feher

Josephine Schafer wrote:
[SNIP]
1. It would be better if you ask this on a Windows NG.

The problem has nothing to do with Windows, all you need to know is that
thread starting function take a void * argument to represent "arguments" for
the thread. That is clearly visible from the error message - even though it
is in German.
2. Please translate the errors to English whenever posting.
Then may be someone here can help you.

I speak no German but Konvertierung is definitely Conversion. What it wants
to convert is void (A::*)(void *) (pointer to a member function of a class A
taking a void * argument and returns nothing) to void (*)(void *): pointer
to a function bla bla. Now it is clear that *if* this conversion is
possible you get no error message. It is also clear from the rules of C++
that this conversion is not possible So even if you did not know that
"nicht möglich" is not possible you could deduce what is the problem.

IMHO if you do not take the time to answer a post... well, just do not take
the time to answer it. No offense meant.
 
A

Attila Feher

Ilia said:
_beginthread() is a C run-time function and has no relationship to
any OS.

_beginthread is *not* a C runtime function. Please refer to the ISO
standard of the C language! Or to this place and look for the C runtime
library documentation: http://www.dinkumware.com
 
J

Josephine Schafer

Ilia Poliakov said:
_beginthread() is a C run-time function and has no relationship to any OS.

Well then it's a C++ NG.
error C2664: '_beginthread' : convertion of parameter 1 from 'void (__cdecl
A::* )(void *)' in 'void (__cdecl *)(void *)' not possible

Your error message gives the answer.
You cannot convert a pointer to a member function to a normal pointer
to a function.
 
S

Simon Saunders

Ilia Poliakov said:
_beginthread() is a C run-time function and has no relationship to any OS.

That is not true. _beginthread is non-standard and specific to Microsoft
Windows.
 
J

Josephine Schafer

Attila Feher said:
Josephine Schafer wrote:
[SNIP]
1. It would be better if you ask this on a Windows NG.

The problem has nothing to do with Windows, all you need to know is that
thread starting function take a void * argument to represent "arguments" for
the thread. That is clearly visible from the error message - even though it
is in German.
2. Please translate the errors to English whenever posting.
Then may be someone here can help you.

I speak no German but Konvertierung is definitely Conversion. What it wants
to convert is void (A::*)(void *) (pointer to a member function of a class A
taking a void * argument and returns nothing) to void (*)(void *): pointer
to a function bla bla. Now it is clear that *if* this conversion is
possible you get no error message. It is also clear from the rules of C++
that this conversion is not possible So even if you did not know that
"nicht möglich" is not possible you could deduce what is the problem.

IMHO if you do not take the time to answer a post... well, just do not take
the time to answer it. No offense meant.

OK may be I just looked at _beginthread() and started taking it OT.
Neither do I understand German nor did I made make much attempts to
understand it.
But when the OP translated the error message, I answered it and yes it had
nothing to do with
Windows or anything as you said.

Hope you too understand.
J.Schafer
 
A

Attila Feher

Josephine said:
Well then it's a C++ NG.

The C libray is part of C++. But of course the _beginthread function is not
part of either. :)
Your error message gives the answer.
You cannot convert a pointer to a member function to a normal pointer
to a function.

I guess why the OP posted is to know what he _can_ do, not only to know that
he cannot do it as he tried. ;-)
 
R

Ron Samuel Klatchko

Ilia Poliakov said:
Can I run a thread with _beginthread() and pass as the first parameter the
pointer on a member function of a class?

#include <process.h>

class A
{
void _cdecl f(void*) {};
};

void main()
{
_beginthread(&A::f, 0, NULL);
}

I get the compilation error:
error C2664: '_beginthread' : Konvertierung des Parameters 1 von 'void
(__cdecl A::* )(void *)' in 'void (__cdecl *)(void *)' nicht moglich

PS. I work in MSVC7.0 (german version :), console application

As has been pointed out by others, a pointer to a member function is
not the same as a pointer to a function.

So, what you want is a function that is compatible with begin thread
and will forward your function correctly.


extern "C" void _cdecl forward_function(void *arg)
{
A *a = reinterpret_cast<A *>(arg);

arg->f();
}

samuel
}
 
J

Jack Klein

Nope. AFAIK _beginthread is a C function, taking a void * argument.

Nope, _beginthread is not a C function. It is not defined anywhere in
the C standard. Nor am I aware of any Microsoft documentation that
states that it is written in (non-standard) C.

What you could say is that _beginthread is a function that may be
called by C.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
H

Hafiz Abid Qadeer

Ilia Poliakov said:
Can I run a thread with _beginthread() and pass as the first parameter the
pointer on a member function of a class?

#include <process.h>

class A
{
void _cdecl f(void*) {};
};

void main()
{
_beginthread(&A::f, 0, NULL);
}

I get the compilation error:
error C2664: '_beginthread' : Konvertierung des Parameters 1 von 'void
(__cdecl A::* )(void *)' in 'void (__cdecl *)(void *)' nicht moglich

PS. I work in MSVC7.0 (german version :), console application

You can use the static member function

I got it compiled with the following code with proper header included

class proc
{
public:
static void SecondThreadFunc( void* pArguments )
{
printf("In thread");
}
};

void main()
{
_beginthread(proc::SecondThreadFunc, 0, NULL );
Sleep(1000);
}

Hope that helps
 
A

Attila Feher

Jack said:
Nope, _beginthread is not a C function. It is not defined anywhere in
the C standard. Nor am I aware of any Microsoft documentation that
states that it is written in (non-standard) C.

It is a C function. Repeat it to yourself until you understand: it *is* a C
function. And then if you still not understand say that: on the other hand
strcpy is a *standard C library* function.
What you could say is that _beginthread is a function that may be
called by C.

Which we call a C function as opposed to C++, Fortran, Fifthrun etc.
functions. If you did care to read my other posts you would have seen that
I did post (to the OP) that _beginthread is not a standard C library
function.
 
A

Attila Feher

Ron said:
So, what you want is a function that is compatible with begin thread
and will forward your function correctly.

And if you want that (forward correctly) you do nto want to use the posted
code.
extern "C" void _cdecl forward_function(void *arg)
{
A *a = reinterpret_cast<A *>(arg);

Reinterpret case is _implementation_ defined. In *all* cases. If you want
to get back your original A pointer here you *must* use static_cast (or a C
style cast).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top