![](/img/trans.png)
[英]How can you pass a function pointer and compare it in a function in C++?
[英]How can I pass generic function pointer in c++?
我要完成的工作是在嵌入式環境中注冊回調。 該回調將采用以下兩種形式之一:
void (*cb) (void *ctxt); or
void ClassA::VirtualFn (void);
該代碼只能在使用GCC的ARM平台上運行。 由於在運行時完成了一些動態綁定,因此注冊回調函數必須是虛擬的。 以上兩個函數在匯編級別都是等效的(它們都使用一個指針)。 此外,出於性能目的,回調機制處於匯編狀態,因為它發生在ISR上下文中,因此我不必為此擔心。 我真正需要的是一個采用以上任何一種並存儲傳遞的函數指針和上下文指針的函數。 即:
void isr_cb (void *ctxt) {}
gpio->RegisterIsr (isr_cb, cptr);
gpio->RegisterIsr (&ClassA::IsrHandler, this);
and indeed everything works as expected (apart from the compiler warnings). 我已經通過將虛擬成員函數強制轉換為 ,實際上一切工作都按預期進行(除了編譯器警告)。
將virtual
成員函數強制轉換為void (*)(void *)
聽起來很苛刻。
你說:
由於在運行時完成了一些動態綁定,因此注冊回調函數必須是虛擬的。
我認為這意味着您具有ClassA
類型的對象。 如果正確,那么您應該:
將ClassA
的static
成員注冊到其簽名為的回調機制中:
void (*)(ClassA& ref);
添加執行實際工作的virtual
成員函數。
void doStuff();
假設已注冊的回調函數為:
static void foo(Class& ref);
在foo
的實現中,對ref
調用doStuff
。
static void foo(Class& ref) { ref.doStuff(); }
如果您可以利用c ++ 11中的std::bind
或boost::bind
,則將擁有更加輕松的時間。 如果接口(即實際輸出類型和實際輸入參數類型相同),則兩者都可以讓您將成員函數指針和自由函數彼此混合使用,例如
int f(double val)
{
}
class A {
int memberf(double val);
}
A instanceOfA;
auto f1 = std::bind(f, std::placeholders::_1);
auto f2 = std::bind(&A::memberf, &instanceOfA, std::placeholders::_1);
現在, f1
和f2
都是帶double
並返回int
函數,而與以下事實無關:一個是成員函數,另一個是自由函數,因此不需要強制轉換。 我不得不承認我不能從內存中寫出實際的類型。
首先,在C和C ++中都沒有通用的函數指針。
完全合格和高性能的解決方案仍然是可能的。
由於非成員函數已經是正確的類型,因此它是微不足道的。
如果您知道可能要傳遞的全套非虛擬成員功能和虛擬功能插槽,請為每個定義一個簡單的轉發器,方法如下:
void forward_to_IsrHandler(void* p) { ((ClassA*)p)->IsrHandler(); } gpio->RegisterIsr (forward_to_IsrHandler, (void*)this);
如果您不知道或真的想在性能方面犧牲標准一致性,則可以將成員函數指針轉換為普通函數指針(gcc擴展,其他編譯器也有自己的) :
void (*tmp)(ClassA*) = (void(*)(ClassA*))&ClassA::IsrHandler;
使用-Wno-pmf-conversions
刪除使用擴展名的警告。
由於在ARM上對函數void(*)(void*)
和void(*)(ClassA*)
的調用看起來完全相同,因此即使嚴格地說是UB,也可以使用它:
gpio->RegisterIsr ((void(*)(void*))tmp, (void*)this);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wno-pmf-conversions"
// Do the foul deed here
#pragma GCC diagnostic pop
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.