另一個答案指出爲什麼你的代碼不起作用。這是一種非常難看的解決方案,適用於某些有限的情況。
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