lundi 27 juillet 2015

Using unique_ptr / shared_ptr with API functions returning resources as out parameters via pointer

I’m catching up now with C++ 11/14 stuff in my current project. I have trouble using unique_ptr/shared_ptr with API functions returning resources as out parameters via pointer.

Let’s consider DsGetDcName(..., __out PDOMAIN_CONTROLLER_INFO* ppDCI) as an example.

Before c++11 there was a widespread pattern to work with Windows APIs. I would have a RIIA class that holds PDOMAIN_CONTROLLER_INFO, calls NetApiBufferFree in destructor, and has PDOMAIN_CONTROLLER_INFO* operator&() so that I can write:

info_ptr spInfo;
DsGetDcName(..., &spInfo);

Now with C++ 11/14 I see a lot of articles advocating for unique_ptr/shared_ptr with a custom deleter to release a resource in a proper way. And it really works well when a resource is returned as an r-value from a function (LoadLibrary is a good example of this).

One solution I found is to attach a raw-pointer to a smart pointer after the API call:

PDOMAIN_CONTROLLER_INFO pDCI = nullptr;
DsGetDcName(..., &pDCI);
std::unique_ptr<DOMAIN_CONTROLLER_INFO, decltype(&NetApiBufferFree)> spInfo(pDCI, &NetApiBufferFree);

However, this is not the way I like. As far as I understand, new smart pointers were not designed to work for out parameters probably because of the ‘safty first’ approach.

Can something be really done here? Perhaps some kind of functor class serving as out parameter proxy so I can write DsGetDcName(..., &out_param(spInfo)) ?

Aucun commentaire:

Enregistrer un commentaire