mam Win32 API CommandLineToArgvW
która zwraca LPWSTR*
i ostrzega mnie, żestd :: unique_ptr z niestandardowym Deleter dla Win32 LocalFree
CommandLineToArgvW
alokuje blok pamięci ciągłej dla wskaźniki do ciągów argumentów, a dla samych łańcuchów argumentów ; aplikacja wywołująca musi zwolnić pamięć używaną przez listę argumentów , gdy nie jest już potrzebna. Aby zwolnić pamięć, użyj pojedynczego połączenia z funkcjąLocalFree
.
Zobacz http://msdn.microsoft.com/en-us/library/windows/desktop/bb776391(v=vs.85).aspx
Co to jest C++ idiomatyczne sposób, aby zwolnić pamięć w powyższym przypadku?
Myślałam do std::unique_ptr
z niestandardowym Deleter, coś takiego:
#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;
}
Czy istnieje jakiś problem w powyższym kodzie?
Nie potrzebujesz 'std :: function' dla ostatniego przykładu, myślę: stateless lambda są zamienne na wskaźniki funkcji. To znaczy. 'std :: unique_ptr p (...)' –
MSalters
@ MSalters Próbowałem tego, ale nie udało się go skompilować pod VC10 i g ++ 4.6.2. Pierwszy z komunikatów o błędach to "błąd C2664:" std :: unique_ptr <_Ty,_Dx> :: unique_ptr (wchar_t *, void (__stdcall * const &) (LPWSTR *)) ': nie można przekonwertować parametru 2 z' anonymous-namespace '::' to 'void (__stdcall * const &) (LPWSTR *)' ' –
Praetorian
@MSalters Masz rację, przechwytywania lambdas można przekonwertować na wskaźnik funkcji, więc' std :: function' nie jest konieczne. Jednak VC10 [nie implementuje tego] (https://connect.microsoft.com/VisualStudio/feedback/details/572138).Nie wiem, jak to zrobiłem, gdy próbowałem po raz pierwszy z g ++, ale na pewno działa. – Praetorian