M
Michael Oswald
Hello all,
I'm working on a project where I came across some situations, where the GUI
library works with normal C callbacks. The code has been implemented by
many people, so I came across different versions of callbacks (see the code
below for 3 variants).
Variant1: a normal static member function is used to redirect the callback
to a member function
Variant2: a static member function is declared, but at the definition the
extern "C" is added
Variant3: a normal C function is used.
Obviously, it works on at least two compilers (gcc 3.3.3 and a Sun compiler,
I don't know the version), as the output is for all 3 cases "member
called", but I remember from a discussion that the first 2 variants are not
legal C++ code.
What does the standard say about this?
Code:
#include <iostream>
typedef void (*func)(void*);
class Foo
{
public:
Foo(bool val)
{
if(val)
{
m_func = &func1;
m_arg = (void*)this;
}
else
{
m_func = &func2;
m_arg = (void*)this;
}
}
Foo(func f) : m_func(f), m_arg((void*)this)
{}
void call()
{
m_func(m_arg);
}
void member()
{
std::cout << "member called" << std::endl;
}
static void func1(void* arg);
static void func2(void* arg);
private:
func m_func;
void* m_arg;
};
// Variant 1: normal static member
void Foo::func1(void* arg)
{
((Foo*)arg)->member();
}
// Variant2: static member with extern "C"
extern "C" void Foo::func2(void* arg)
{
((Foo*)arg)->member();
}
// Variant3: normal function
extern "C" void func3(void* arg)
{
((Foo*)arg)->member();
}
int main()
{
Foo foo1(true);
Foo foo2(false);
Foo foo3(func3);
foo1.call();
foo2.call();
foo3.call();
return 0;
}
I'm working on a project where I came across some situations, where the GUI
library works with normal C callbacks. The code has been implemented by
many people, so I came across different versions of callbacks (see the code
below for 3 variants).
Variant1: a normal static member function is used to redirect the callback
to a member function
Variant2: a static member function is declared, but at the definition the
extern "C" is added
Variant3: a normal C function is used.
Obviously, it works on at least two compilers (gcc 3.3.3 and a Sun compiler,
I don't know the version), as the output is for all 3 cases "member
called", but I remember from a discussion that the first 2 variants are not
legal C++ code.
What does the standard say about this?
Code:
#include <iostream>
typedef void (*func)(void*);
class Foo
{
public:
Foo(bool val)
{
if(val)
{
m_func = &func1;
m_arg = (void*)this;
}
else
{
m_func = &func2;
m_arg = (void*)this;
}
}
Foo(func f) : m_func(f), m_arg((void*)this)
{}
void call()
{
m_func(m_arg);
}
void member()
{
std::cout << "member called" << std::endl;
}
static void func1(void* arg);
static void func2(void* arg);
private:
func m_func;
void* m_arg;
};
// Variant 1: normal static member
void Foo::func1(void* arg)
{
((Foo*)arg)->member();
}
// Variant2: static member with extern "C"
extern "C" void Foo::func2(void* arg)
{
((Foo*)arg)->member();
}
// Variant3: normal function
extern "C" void func3(void* arg)
{
((Foo*)arg)->member();
}
int main()
{
Foo foo1(true);
Foo foo2(false);
Foo foo3(func3);
foo1.call();
foo2.call();
foo3.call();
return 0;
}