[英]C++: closure to pass member function as normal function pointer
我正在嘗試調用外部庫的成員函數,該函數將函數指針作為參數:
Timer::every(unsigned long period, void (*callback)(void));
但不幸的是,我想傳遞的參數是一個成員函數:
void MyClass::the_method_i_want_to_pass(void);
由於我正在為Arduino(AVR)下的ATMega編程,因此對c ++ 11的支持有限。 我的第一種方法引發了類型錯誤:
void MyClass::the_method_i_want_to_pass() {...}
MyClass::MyClass() {
// constructor
Timer *timer = new Timer();
timer->every(500, [this](){this->the_method_i_want_to_pass();})
}
編譯器輸出:
警告:警告:lambda表達式僅適用於-std = c ++ 11或-std = gnu ++ 11 [默認啟用]
錯誤:沒有匹配函數來調用'Timer :: every(int,MyClass :: MyClass():: __ lambda0)'
你的基本問題是你的Timer
庫寫得很糟糕:它至少應該是void(*)(void*), void*
。
沒有pvoid或等價物,您不能傳遞執行代碼中的地址以外的任何狀態來運行該過程。 作為一種方法也可以重新使用this
指針,你運氣不好。
現在,如果您的MyClass
實例是單例,您可以從其他地方獲取this
實例。
如果做不到這一點,您需要創建自己的全局狀態,以便從特定回調映射到某個狀態。 如果您擁有有限數量的MyClass
和其他Timer
,您可以擁有一些固定的功能,並讓它們在全局存儲其額外狀態。
這都是黑客攻擊。 接下來的情況更糟。
編寫一個具有某種全局狀態和void()
接口的動態庫。 添加回調時,復制該動態庫,在運行時修改其全局狀態,將其寫為不同名稱的庫,加載它,並將純回調函數傳遞給Timer
類。
或者通過手動編寫機器代碼並將頁面標記為可執行來在沒有庫的情況下進行等效。
這些都是糟糕的解決方案。 這讓我找到了一個好的:找到一個更好的Timer
。 如果他們搞砸了一些簡單的東西,那么圖書館的其他部分也可能很糟糕。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.