簡體   English   中英

C ++:閉包傳遞成員函數作為普通函數指針

[英]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)'

  1. 還有其他/更好的解決方案嗎?
  2. 關於我目前的方法:(如何)當需要函數指針時,是否可以傳遞對lambda的引用?
  3. 如何判斷Arduino / AVR是否支持這些lambdas(參見“警告”)?

你的基本問題是你的Timer庫寫得很糟糕:它至少應該是void(*)(void*), void*

沒有pvoid或等價物,您不能傳遞執行代碼中的地址以外的任何狀態來運行該過程。 作為一種方法也可以重新使用this指針,你運氣不好。

現在,如果您的MyClass實例是單例,您可以從其他地方獲取this實例。

如果做不到這一點,您需要創建自己的全局狀態,以便從特定回調映射到某個狀態。 如果您擁有有限數量的MyClass和其他Timer ,您可以擁有一些固定的功能,並讓它們在全局存儲其額外狀態。

這都是黑客攻擊。 接下來的情況更糟。

編寫一個具有某種全局狀態和void()接口的動態庫。 添加回調時,復制該動態庫,在運行時修改其全局狀態,將其寫為不同名稱的庫,加載它,並將純回調函數傳遞給Timer類。

或者通過手動編寫機器代碼並將頁面標記為可執行來在沒有庫的情況下進行等效。

這些都是糟糕的解決方案。 這讓我找到了一個好的:找到一個更好的Timer 如果他們搞砸了一些簡單的東西,那么圖書館的其他部分也可能很糟糕。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM