[英]Using an intermediary function to direct a callback to a member function
我相信這個問題類似於這個問題。 但是我不確定如何根據我的情況進行調整。 這就是我在做什么。
我目前有這樣的東西
void IOCompletionCallback(_In_ DWORD dwErrorCode, _In_ DWORD dwNumberOfBytesTransfered, _Inout_ LPOVERLAPPED lpOverlapped)
{
......
}
void foo::Work()
{
if (!BindIoCompletionCallback(hnd, IOCompletionCallback, 0))
{
printf("Error (error code: %u)\n", GetLastError());
}
}
在上面的代碼中,我使用的是 windows API BindIoCompletionCallback
,它接受 function IOCompletionCallback
。 我想做的是實際上使IOCompletionCallback
成為 foo 的方法而不是免費的 function 所以我可以這樣做
if (!BindIoCompletionCallback(hnd, std::bind( &foo::IOCompletionCallback,this), 0))
{
}
但我讀到這是不可能的,因為該方法的簽名采用特定類型。 從我發布的鏈接中可以看出,您可以使用中介方法。 我不確定我如何能夠將實例地址傳遞給該中間方法。 對這種方法的任何建議將不勝感激。
使用您創建並傳遞給 io 操作的 lpoverlapped 來存儲回調。 嗯,重疊之前/之后的數據。這個 function 應該只是將重疊轉換為更大的 state,找到你存儲在那里的回調,並調用那個回調。
回調可以是 std function 及其所有出色的實用程序。
template<class D>
struct MyOverlapped:OVERLAPPED{
std::function<void(DWORD, DWORD, D*)> callback;
MyOverlapped():OVERLAPPED{0}{}
virtual ~MyOverlapped() {}
};
有點像這樣。 你會像這樣使用它:
template<class D>
void MyIOCompletionCallback(_In_ DWORD dwErrorCode, _In_ DWORD dwNumberOfBytesTransfered, _Inout_ LPOVERLAPPED lpOverlapped)
{
if (!lpOverlapped) return;
auto* pOverlapped = static_cast<D*>(lpOverlapped);
pOverlapped->callback( dwErrorCode, dwNumberOfBytesTransferred, pOverlapped );
delete pOverlapped; // as MyOverlapped
}
struct ReadFileOverlapped: MyOverlapped<ReadFileOverlapped> {
explicit ReadFileOverlapped(std::size_t count = 0) {
data.resize(count);
}
DWORD size() const { return static_cast<DWORD>(data.size()); }
std::vector<std::byte> data;
};
auto overlapped = std::make_unique<ReadFileOverlapped>(1024);
overlapped->callback = [=](_In_ DWORD dwErrorCode, _In_ DWORD dwNumberOfBytesTransfered, ReadFileOverlapped* pOverlapped ) {
std::cout << "Error " << dwErrorCode << "\n";
std::cout << "Bytes " << dwNumberOfBytesTransfered << "\n";
// get at data in pOverlapped->data.data() through pOverlapped->data.data()+dwNumberOfBytesTransfered or somesuch
};
if (ReadFile( hnd,
overlapped->data.data(),
overlapped->size(),
nullptr,
overlapped.get()
)) {
if (BindIoCompletionCallback(hnd, MyIOCompletionCallback<ReadFileOverlapped>, 0))
{
overlapped.release();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.