3

I'm currently developing a cross-platform shared library in C++ and came across the problem of memory management across module boundaries, ie, releasing memory allocated in my shared library in the process that calls it.

I've been down the list of possible solutions for this - using a C interface, using only pure abstract interfaces and using CoTaskMemAlloc/CoTaskMemFree and the latter seems to be the easier one.

Has anyone tried to make standard smart pointers work with these two methods? Are there any smart pointer implementations that use these methods so smart pointers can be shared across DLL boundaries?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
ruipacheco
  • 15,025
  • 19
  • 82
  • 138

3 Answers3

2

Try to look to: CComHeapPtr CHeapPtr

Dmitry Ivanov
  • 508
  • 7
  • 9
1

You can use CComHeapPtr (as suggested here):

Example:

#include <atlbase.h>
....
CComHeapPtr<WCHAR> pszPath;
if (SHGetKnownFolderPath(FOLDERID_ProgramData, 0, nullptr, &pszPath) != S_OK)
    return {};
return std::wstring(pszPath);

Instead of:

PWSTR pszPath;
if (SHGetKnownFolderPath(FOLDERID_ProgramData, 0, nullptr, &pszPath) != S_OK)
    return {};
std::wstring ret = pszPath;
CoTaskMemFree(pszPath);
return ret;
MrTux
  • 32,350
  • 30
  • 109
  • 146
0

In the past, I tried something similar to this.

    template<typename T>
    struct freeArrFunctor
    {
        void operator()(T* arr)
        {
            free(arr);
            arr = NULL;
        }
    };

    template<typename T>
    using unique_array_ptr = std::unique_ptr<T, freeArrFunctor<T>>;

    template<typename T>
    inline unique_array_ptr<T> make_unique_array_ptr (const size_t Nbyte)
    {
        return unique_array_ptr<T>(static_cast<T*>(malloc(Nbyte)));
    }

First, you have to declare the way your own deleter will work (here I used the c 'free()' function). and use is as a custom deleter to the unique pointer.

You can have a look to this topic where there is a lot of good example of custom usage of unique pointer.

So based on the example above, you can make a derived smart pointer like:

cross_unique_ptr<T> where you will be able to defined your own make function (if you want to, else construct directly the pointer), and also define the cross_deleter_functor to provide to that new smart pointer.

Vuwox
  • 2,331
  • 18
  • 33
  • I meant overloading smart pointers to always use those two methods, but I appreciate your idea. – ruipacheco Sep 24 '19 at 14:09
  • I don't think it is a good idea to overload the smart pointer, you should prefer to `wrap` them as your title suggest. – Vuwox Sep 24 '19 at 14:14
  • This means I'll need a wrap for each type I need to store a pointer to. That's a lot of work. – ruipacheco Sep 24 '19 at 14:19
  • 1
    You have two options. You can redefined the `::std::default_delete` and the `::std::make_unique` for each type as shown [here](https://stackoverflow.com/a/50957671/1524511), or you can create a newer object like `cross_unique_ptr` (as I shown in my answer) and use it instead of a `std::unique_ptr` – Vuwox Sep 24 '19 at 14:21