Интеллектуальное управление памятью указателя через границу DLL с объектно-ориентированным API - PullRequest
0 голосов
/ 11 мая 2018

Я думаю, что следующие классы безопасны для предоставления из DLL как часть API, потому что они содержат только чистые виртуальные члены.

namespace myapi {
    struct Image {
        virtual int width() = 0;
        virtual int height() = 0;
        virtual unsigned char* data() = 0;
        virtual void dispose() = 0; // will `delete this` from inside the DLL
    }

    struct Camera {
        virtual Image* getFrame() = 0; // caller owns the returned object
    }
}

Пользователь API должен запомнить dispose() для указателя, возвращенного Camera::getFrame(). Чтобы снять это бремя с пользователя, я хочу изменить заголовочный файл так:

namespace myapi {
    template<typename T>
    using unique_ptr = std::unique_ptr<T, std::function<void(T*)>>;

    struct Image {
        virtual int width() = 0;
        virtual int height() = 0;
        virtual unsigned char* data() = 0;
        virtual ~Image(){};
    }

    struct Camera {
        unique_ptr<Image> getFrame(){
            return unique_ptr<Image>(getFrameRaw(), [](auto* i){deleteImage(i);});
        }
    private:
        virtual Image* getFrameRaw() = 0; // caller owns the returned object
    }
    extern "C" MYAPI_API void deleteImage(Image* i); // will `delete i` from inside DLL
}

Это так же безопасно, как и первая версия? class Camera больше не имеет только чистых виртуальных членов, но не виртуальный член находится прямо в файле заголовка для встроенного EXE-файла. Значит ли это, что я делаю безопасно?

...