簡體   English   中英

使用中介 function 將回調定向到會員 function

[英]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.

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