From 8862696926173104957729683832591438161557 Mon Sep 17 00:00:00 2001 From: Glenn Smith Date: Fri, 27 Dec 2024 16:14:46 -0500 Subject: Render Layers --- ffi.h | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'ffi.h') diff --git a/ffi.h b/ffi.h index f9686cb5..15654c5f 100644 --- a/ffi.h +++ b/ffi.h @@ -65,6 +65,86 @@ namespace BinaryNinja //endregion + //region Generic API Objects + + /*! Helper class to determine if a type is "API-able" aka has the following interface: + + struct Foo + { + BNFoo GetAPIObject() const; + static Foo FromAPIObject(const BNFoo* obj); + static void FreeAPIObject(BNFoo* obj); + }; + + If you get weird compiler errors around here, make sure you've implemented + the above interface correctly (with the `const`s too!). + */ + template< + typename T, + // Grab the type for TAPI from the return type of GetAPIObject() + // Store into template argument for easier lookup + typename TAPI_ = decltype(std::declval().GetAPIObject()) + > + // Subtype of bool_constant to allow std::enable_if usage + struct APIAble : std::bool_constant< + // Make sure T::FromAPIObject(TAPI*) actually works + std::is_invocable_v + // Make sure T::FromAPIObject(TAPI*) returns T + && std::is_same_v()))> + // Make sure T::FreeAPIObject(TAPI*) actually works + && std::is_invocable_v + > + { + // For reference by users of APIAble + typedef TAPI_ TAPI; + }; + + template::value, void>> + void AllocAPIObjectList(const std::vector& objects, typename APIAble::TAPI BN_API_PTR** output, size_t* count) + { + *count = objects.size(); + *output = new typename APIAble::TAPI[objects.size()]; + + size_t i = 0; + for (const auto& o: objects) + { + (*output)[i] = o.GetAPIObject(); + i ++; + } + } + + template::value, void>> + typename APIAble::TAPI BN_API_PTR* AllocAPIObjectList(const std::vector& objects, size_t* count) + { + typename APIAble::TAPI* result; + AllocAPIObjectList(objects, &result, count); + return result; + } + + template::value, void>> + std::vector ParseAPIObjectList(const typename APIAble::TAPI* objects, size_t count) + { + std::vector result; + result.reserve(count); + for (size_t i = 0; i < count; i ++) + { + result.push_back(T::FromAPIObject(&objects[i])); + } + return result; + } + + template::value, void>> + void FreeAPIObjectList(typename APIAble::TAPI BN_API_PTR* objects, size_t count) + { + for (size_t i = 0; i < count; i ++) + { + T::FreeAPIObject(&objects[i]); + } + delete[] objects; + } + + //endregion + //------------------------------------------------------------------------------------ //region Try/Catch Helpers -- cgit v1.3.1