2012-06-04 48 views
1

我有一個函數Foo這需要一個2參數函數作爲參數:解析外部符號,自制委託

void Foo(void (*fcn)(int, int*)); 

然而,我想通過在函數類型(func)僅需1參數*

typedef void (__stdcall *FuncCallBack)(int a); 

void Caller(FuncCallBack func) { 
    Foo(????); 
} 

在C#中,我會做這樣的事情:

Foo((a,b) -> func(a)); 

我試圖做一個委託類類似的東西(已經制定了,我不能有一個指針到綁定成員函數,我已經轉換爲靜態):

class Delegate { 
private: 
static FuncCallBack _Callback; 
public 
Delegate(FuncCallBack); 
static void Callback(int, int*); 
} 

Delegate::Delegate(FuncCallback callback) { _Callback = callback; } 

void Delegate::Callback(int a, int *b) { _Callback(a); } 

我用像這樣:

void Caller(FuncCallBack func) { 
    Delegate d = Delegate(func); 
    Foo(&(d.Callback)); 
} 

這是目前給我一個鏈接錯誤:unresolved external symbol "private: static void (__stdcall* Delegate::_Callback)(int)" ([email protected]@@[email protected])

  • 問題1:是什麼導致這個鏈接錯誤?
  • 問題2:有沒有更好的辦法做到這一點?

*的typedef包括__stdcall因爲它是從傳遞(和將調用回)函數C#)

+1

我認爲有一個'Delegate'類是針對這種情況一個壞主意。這是給你已經包裹的功能類實例的錯覺,而在現實中實際調用的函數取決於如何構建'Delegate'的最後一個實例與構建。'Delegate :: _ Callback'實際上是全局數據。 –

+0

@CharlesBailey,是的,我意識到,那麼你會怎麼做,不要假裝,只是把它變成一個全球性的功能呢? – Benjol

回答

2

正如我在我的評論中指出,使用一個類使它看起來就像你包裹回調函數的類實例,但作爲回調函數是原始函數指針不能從類訪問任何狀態它從中獲得的實例。它只能訪問靜態成員變量,這意味着行爲都Delegate情況下,每當一個新的Delegate實例構造。

如果你不得不支持調用不同的func我會使用一個更簡單的接口,使得只有回調函數在接口中更加明顯。

例如:

callbackwrapper.h

void CallbackWrapper(int, int*); 
void SetWrappedCallback(void (__stdcall *toWrap)(int)); 

callbackwrapper.cpp

namespace { 
    void (__stdcall *wrappedCallback)(int); 
} 

void CallbackWrapper(int a, int*) 
{ 
    wrappedCallback(a); 
} 

void SetWrappedCallback(void (__stdcall *toWrap)(int)) 
{ 
    wrappedCallback = toWrap; 
} 
2

您需要定義類的static成員,一次(在委託。 CPP爲例):

FuncCallBack Delegate::_Callback; 

在發佈的代碼中只有一個聲明_Callback

+0

優秀!謝謝。在C#中工作了很多年,在C++ – Benjol

+0

@Benjol中產生了一點經驗,oops。感謝您的編輯。 – hmjd