Я думаю, что следующие классы безопасны для предоставления из 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-файла. Значит ли это, что я делаю безопасно?