繁体   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