std::unique_ptr,为win32 LocalFree自定义删除器。

我有win32的API CommandLineToArgvW 其中返回一个 LPWSTR* 并警告我说

CommandLineToArgvW 为指向参数字符串的指针和参数字符串本身分配一个连续的内存块;当参数列表不再需要时,调用应用程序必须释放参数列表使用的内存。要释放内存,请使用一个对 LocalFree 功能。

http:/msdn.microsoft.comen-uslibrarywindowsdesktopbb776391(v=vs.85).aspx。

在上述情况下,有什么C++的习惯性方法可以释放内存?

我在想对一个 std::unique_ptr 用一个自定义的删除器,类似的东西。

#include <Windows.h>
#include <memory>
#include <iostream>

template< class T >
struct Local_Del
{
   void operator()(T*p){::LocalFree(p);}
};

int main(int argc, char* argv[])
{
   {
      int n = 0;
      std::unique_ptr< LPWSTR, Local_Del< LPWSTR > > p( ::CommandLineToArgvW(L"cmd.exe p1 p2 p3",&n) );
      for ( int i = 0; i < n; i++ ) {
         std::wcout << p.get()[i] << L"\n";
      }
   }

    return 0;
}

上面的代码有什么问题吗?

解决方案:

在我看来是正确的。你可以把它弄得更简洁一些,通过指定的 unique_ptr的 deleter inline,而不是为它创建一个漏斗。

std::unique_ptr<LPWSTR, HLOCAL(__stdcall *)(HLOCAL)> 
      p( ::CommandLineToArgvW( L"cmd.exe p1 p2 p3", &n ), ::LocalFree );

或者,如果你不想弄脏 LocalFree的签名和调用约定,你可以使用lambda来进行删除。

std::unique_ptr<LPWSTR, void(*)(LPWSTR *)> 
      p( ::CommandLineToArgvW( L"cmd.exe p1 p2 p3", &n ), 
         [](LPWSTR *ptr){ ::LocalFree( ptr ); } );

注意:在这个答案第一次写出来的时候,VS2010是已经发布的VS版本。 在这个答案第一次写的时候,VS2010是发布的VS版本。它 不支持 将无捕获的lambdas转换为函数指针,所以你必须使用 std::function 在第二个例子中

std::unique_ptr<LPWSTR, std::function<void(LPWSTR *)>> 
      p( ::CommandLineToArgvW( L"cmd.exe p1 p2 p3", &n ), 
         [](LPWSTR *ptr){ ::LocalFree( ptr ); } );

给TA打赏
共{{data.count}}人
人已打赏
未分类

使用Rust中的`tokio-rustls`从TlsStream<TcpStream>读取。

2022-9-8 0:44:22

未分类

TFIDF和多语种文本分类

2022-9-8 0:55:17

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索