I have a third-party library which has a method that takes a function pointer as the first parameter:
int third_party_method(void (*func)(double*, double*, i
Is there any way I can pass the member to the function?
Unless your class object is some kind of global object - it is not possible. Because objects may contain some data, while function pointer is just pointer to function - it doesn't contain any runtime context, only compile-time one.
If you accept having compile-time unique IDs for each callback passing, then you can use following generalized approach.
Usage:
void test(void (*fptr)())
{
fptr();
}
struct SomeStruct
{
int data;
void some_method()
{
cout << data << endl;
}
void another_method()
{
cout << -data << endl;
}
};
int main()
{
SomeStruct local[] = { {11}, {22}, {33} };
test(get_wrapper<0>( boost::bind(&SomeStruct::some_method,local[0]) ));
test(get_wrapper<1>( boost::bind(&SomeStruct::another_method,local[0]) ));
test(get_wrapper<2>( boost::bind(&SomeStruct::some_method,local[1]) ));
test(get_wrapper<3>( boost::bind(&SomeStruct::another_method,local[1]) ));
test(get_wrapper<4>( boost::bind(&SomeStruct::some_method,local[2]) ));
test(get_wrapper<5>( boost::bind(&SomeStruct::another_method,local[2]) ));
}
It may not require Unique ID's for each invocation, for instance because Functors may already have different types, or runtime scope of their usage do not overlap. But it is safer to use unique ID each time.
Implementation:
live demo
#include
#include
#include
#include
using namespace std;
template
boost::optional &get_local()
{
static boost::optional local;
return local;
}
template
typename Functor::result_type wrapper()
{
return get_local().get()();
}
template
struct Func
{
typedef ReturnType (*type)();
};
template
typename Func::type get_wrapper(Functor f)
{
(get_local()) = f;
return wrapper;
}
// ----------------------------------------------------------------------
void test(void (*fptr)())
{
fptr();
}
struct SomeStruct
{
int data;
void some_method()
{
cout << data << endl;
}
void another_method()
{
cout << -data << endl;
}
};
int main()
{
SomeStruct local[] = { {11}, {22}, {33} };
test(get_wrapper<0>( boost::bind(&SomeStruct::some_method,local[0]) ));
test(get_wrapper<1>( boost::bind(&SomeStruct::another_method,local[0]) ));
test(get_wrapper<2>( boost::bind(&SomeStruct::some_method,local[1]) ));
test(get_wrapper<3>( boost::bind(&SomeStruct::another_method,local[1]) ));
test(get_wrapper<4>( boost::bind(&SomeStruct::some_method,local[2]) ));
test(get_wrapper<5>( boost::bind(&SomeStruct::another_method,local[2]) ));
}
P.S. Beaware of multi-thread access - in such cases you should use some kind of Thread-local storage data.