2014-02-17 72 views
1

我有點複雜的類。C++:回調類

在這個類中我有一個參考:

_COM_SMARTPTR_TYPEDEF(IEtApi, __uuidof(IEtApi)); 

IEtApiPtr有一個名爲作廢 「SetRawDataCB」

virtual HRESULT __stdcall SetRawDataCB (
    /*[in]*/ long address, 
    /*[in]*/ long userData, 
    /*[out,retval]*/ enum ApiError * pRetVal) = 0; 

Private: 
     IEtApiPtr _pIEtApi; 

IEtApiPtr是在.tlh文件中定義我已經在類中定義了一個回調函數:

void CETAPI::RawDataCB(RawData& r, void* userData) 
{ 
    //do something 
} 

現在我想安裝使用

_pIEtApi->SetRawDataCB((long)(__int64)(&RawDataCB),0,&result); 

回調...編譯器告訴我:「錯誤C2276:一個綁定的成員函數的表達式無效操作」。

我在這裏做錯了什麼?

回答

0

這不起作用,因爲RawDataCB是一個不是全局函數的成員函數。您可以將RawDataCB聲明爲類中的靜態函數,如下所示,這將起作用。但是,除非將其作爲參數添加到RawDataCB,並且可能讓RawDataCB成爲朋友,以便訪問類的私有數據(如成員函數可能具有的內容),否則您將不再訪問this指針(即,沒有成員變量)。這可以通過更新函數聲明如下進行:

class CETAPI { 
    static void RawDataCB(RawData& r, void* userData); 
}; 

或者,您可以將指針傳遞給RawDataCB作爲一個成員函數指針,而不是一個函數指針。可以如下操作成員函數指針,因此您只需將RawDataCBType類型的對象傳遞給SetRawDataCB即可。

typedef void (CETAPI::*RawDataCBType)(RawData&, void*); // typedef the member function pointer type 
RawDataCBType pmf = &CETAPI::RawDataCB; // create and initialize a pointer to the member function 
pCETAPIObject->*pmf(r, userData); // call the member function on an object of type CETAPI 

Here是一篇談論成員指針的好文章。

+0

我無法聲明類本身內的回調?換句話說:我可以說myClass-> CreateCallback();而這個類本身會自己創建一個回調? – tmighty

+0

@tmighty當您在類中聲明函數時,它具有與在類之外聲明它不同的特徵(除非使用static關鍵字在類中聲明它)。這是因爲在類中聲明一個函數使其成爲非靜態成員函數。非靜態成員函數與全局函數不同,它們具有不同的簽名,指向指向不同類型的指針。成員函數可以訪問每個對象的局部變量。 – Apriori

+0

@tmighty他們這樣做是因爲他們隱式地傳遞了'this'指針,一個指向成員函數被調用的對象的指針。這個問題更加複雜,因爲你的函數是虛擬的,你確實需要這個指針,因爲這個指針指向的東西包含一個指向虛擬表的指針,在運行時需要這個指針來解析被調用的實際函數。 – Apriori

0

在這種情況下編譯器在語法 使用以下的代碼行創立問題

pIEtApi-> SetRawDataCB((長)( _int64)(& CETAPI :: RawDataCB),0,&結果);

看到該鏈接以獲得更多信息Error code description