另一个答案指出为什么你的代码不起作用。这是一种非常难看的解决方案,适用于某些有限的情况。
typedef int (*ftwpt)(const char*, const struct stat*, int);
typedef boost::function<int(const char*, const struct stat*, int)> MyFTWFunction;
template <MyFTWFunction *callback>
class callback_binder {
public:
static int callbackThunk(const char *s, const struct stat *st, int i) {
return (*callback)(s, i);
}
};
extern void register_callback(callback_t f);
int random_func(const char *s, const struct stat *st, int i)
{
if (s && *s) {
return i;
} else {
return -1;
}
}
MyFTWFunction myfunc;
int main(int argc, const char *argv[])
{
myfunc = random_func;
register_callback(&callback_binder<&myfunc>::callbackThunk);
return 0;
}
使用指针作为模板参数的规则要求作为参数传入的指针是指向全局变量的指针。当然,该全局变量可以在匿名名称空间中声明。
这很丑陋,如果你想有几个可能的myMap实例可能会被调用,同时你需要尽可能多的全局MyFTWFunction变量同时发生myMap的实例。大多数情况下,这会自动创建使用全局变量内容填充缺失参数的thunk函数。
这里是一个版本,是少了很多灵活的,做大致相同的事情这条狭窄的情况下,可能使之更明显这是怎么回事上:
#include <map>
#include <string>
using ::std::map;
using ::std::string;
typedef map<string, double*> myMap;
typedef int (*callback_t)(const char *, struct stat *st, int);
int myFunction(const char*, struct stat *st, int, myMap*);
template <myMap **map_ptr>
class myMap_binder {
public:
static int call_my_function(const char *s, struct stat *st, int i) {
return myFunction(s, st, i, *map_ptr);
}
};
extern void register_callback(callback_t f);
myMap *mainmap;
myMap *othermap;
int main(int argc, const char *argv[])
{
myMap m_map;
myMap m_map2;
mainmap = &m_map;
othermap = &m_map2;
register_callback(&myMap_binder<&mainmap>::call_my_function);
register_callback(&myMap_binder<&othermap>::call_my_function);
return 0;
}
正如你可以看到myMap_binder是一个模板它会自动生成填充全局变量内容的thunk函数,以调用您的回调函数。
@Konrad对其他问题也解释了为什么你的代码失败:http://stackoverflow.com/questions/282372/demote-boostfunction-to-a-plain-function-pointer/512233 #512233 – 2009-09-04 20:01:45
@HazyBlueDot - 这个问题是关于C++,而不是C.请尝试正确标记它。 – 2009-09-05 02:03:56