This pointer question!

A

amirr

Guys,

As you know static member functions do not have a this pointer. so
instead, what shall i do?

for example ... consider I want to call

Code: ( text )

1.
pthread_create(&thID,NULL,classA::B, (void *) this);



and it is called in an static method so instead of this what can I
put??

Thanks,

Amir.
 
I

Ian Collins

Guys,

As you know static member functions do not have a this pointer. so
instead, what shall i do?

for example ... consider I want to call

Code: ( text )

1.
pthread_create(&thID,NULL,classA::B, (void *) this);
An off topic but common question. You must pass an extern "C" linkage
function to C library functions that expect a function pointer as one of
their parameters.

You *must* not pass a class member function and *should* not pass a
static member function.
 
M

Michael DOUBEZ

Ian Collins a écrit :
An off topic but common question. You must pass an extern "C" linkage
function to C library functions that expect a function pointer as one of
their parameters.

You *must* not pass a class member function and *should* not pass a
static member function.

I didn't know about the static member function. Why is that (some
portability issue on their representation I presume)?

You can use template along the following pattern (using intermediary
class or not, using richer templatization ...):

//! execute member function
template<class T>
void* pthread_class_threadifier(void* param)
{
//better to add try/catch otherwise, stack unwinding doesn't happen
in some cases
std::auto_ptr<std::pair<T*,void(T::*)()> > p(
reinterpret_cast<std::pair<T*,void(T::*)()>*>(param));

((p->first)->*(p->second))();

return NULL;
}

//! start thread on given method of given class
template<class T>
int pthread_create_class(pthread_t& thID, T& object, void (T::*method)())
{
std::pair<T*,void (T::*)()>* param=
new std::pair<T*,void (T::*)()>(&object,method);

int ret= pthread_create(&thID,NULL,
pthread_class_threadifier<T>,
reinterpret_cast<void*>(param));

if(ret)delete param;

return ret;
}

And then:
//test class
class A
{
public:
//this method will be threadified
void a()
{
std::cout<<"OK"<<std::endl;
}
};

int main()
{

A a1;
pthread_t pid;

//create thread
int ret=pthread_create_class(pid,a1,&A::a);
if (ret)
{
std::cerr<<"Error: "<<ret<<std::endl;
}

//wait a bit
::sleep(1);

return 0;
}



Michael
 
I

Ian Collins

Michael said:
Ian Collins a écrit :

I didn't know about the static member function. Why is that (some
portability issue on their representation I presume)?
There is no guarantee that any C++ function will have the same linkage
as a C function. In practice most non-member functions do, but the
compiler is free to issue a diagnostic when one is passed to a function
expecting an extern "C" function pointer.
You can use template along the following pattern (using intermediary
class or not, using richer templatization ...):
This isn't strictly correct (but it will probably work) as function
templates can not have extern "C" linkage.
 
J

James Kanze

There is no guarantee that any C++ function will have the same linkage
as a C function. In practice most non-member functions do, but the
compiler is free to issue a diagnostic when one is passed to a function
expecting an extern "C" function pointer.

Not "free to", required to. Linkage is part of type, and
passing a function with "C++" linkage to pthread_create is just
as much an error as passing one which takes an int instead of a
pointer, or which returns void, instead of void*.

With regards to Michael's code, I don't think a template
instantiation can have C linkage, so the code is illegal.
This isn't strictly correct (but it will probably work) as function
templates can not have extern "C" linkage.

In which case, a good compiler, in strictly conforming mode,
should refuse to compile the code. (Note that both g++ and VC++
get this wrong.)
 
I

Ian Collins

James said:
Not "free to", required to. Linkage is part of type, and
passing a function with "C++" linkage to pthread_create is just
as much an error as passing one which takes an int instead of a
pointer, or which returns void, instead of void*.
Agreed, but many (most?) don't. Sun CC is the only compiler I know that
does object.
 
G

Gennaro Prota

Agreed, but many (most?) don't. Sun CC is the only compiler I know that
does object.

Of course the EDG front-end in strict mode rejects it as well, though
not all EDG-based compilers do. The front-end offers the
--implicit_extern_c_type_conversion and
--no_implicit_extern_c_type_conversion options to control this, but it
is up to the compiler writer whether they are made available to the
user (of course, the conversion cannot work if the compiler uses
incompatible calling conventions for C and C++ functions).
 
?

=?iso-8859-1?q?Kirit_S=E6lensminde?=

Guys,

As you know static member functions do not have a this pointer. so
instead, what shall i do?

for example ... consider I want to call

Code: ( text )

1.
pthread_create(&thID,NULL,classA::B, (void *) this);

and it is called in an static method so instead of this what can I
put??

If you can you're much better off using Boost::threads for this. The
following is off the top of my head:

#include <boost/bind.hpp>
#include <boost/thread/thread.hpp>

class A {
public:
void a() { std::cout << "The A" << std::endl; }
} anA;

int main() {
boost::thread theThread( boost::bind( &A::a, anA ) );
theThread.join();
return 0;
}

Your example would look like more like this:

boost::thread t( boost::bind( &classA::B, this ) );
// Do something else
t.join(); // Wait for this->B() to finish


K
 
J

James Kanze

On May 28, 4:07 pm, (e-mail address removed) wrote:
If you can you're much better off using Boost::threads for this.

It depends. The conception of Boost::threads is far from
perfect, and it's all to easy to accidentally get a detached
thread due to an unexpected exception. The advantages of
Boost::threads limit themselves to: 1) they've already wrapped
the system API, so you don't have to learn both Windows and
Posix, and worry about system dependant code yourself, and 2) in
cases where you want to view the new thread as a functional
object, with its own totally independant lifetime,
Boost::threads has already handled the copying and the
synchronization issues at thread start up for you. (2 is almost
always the case for detached threads, rarely however for
joinable threads.)
 

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

Forum statistics

Threads
474,294
Messages
2,571,511
Members
48,199
Latest member
MarielIzzo

Latest Threads

Top