0

I'm trying to make few small RAII wrappers around C library, and struggling with all the consequences of OOP style solutions, like too keep solution consistent I need to cover all methods of the C library to use it, and on top of that then write own application classes, some methods cant be mapped straightforward, some wrapping techniques breaks decomposition and SoC, or some calls will become overly expensive to execute as I'd need to create hierarchy of correct mapped C++ wrappers for each C type, and etc.

I started to think, what if I wrap C returned opaque resource handles into RAII object, but would not encapsulate the access to it? Or at least I can overload implicit type casting operator back to original C type. I didn't see someone doing it this way, and can't come up with significant cons of the solution, as generally I'm a C style programming guy rather then C++. But RAII and exceptions are quite nice features that I can utilize, therefore trying to have C library with RAII without OOP overhead where I don't need it.

Example of what I want to do:

struct RAIIWrapper {
    RAIIWrapper() {
       pointer = CLibraryCreateCall();
    }
    ~RAIIWrapper() {
       CLIbraryDestroyCall(pointer);
    }
    operator CLibraryPointerType() const { return pointer; }
    CLibraryPointerType pointer;
};

int main() {
    auto riw = RAIIWrapper();
    
    CLibraryMethodCall(riw);

    return 0;
}

Note 1: it doesn't matter if it's templated and universal solution, or manual for each handler type, I'm just probing the concept.
Note 2: smart pointers are not working for me, as those working with pointers, and I need dynamically allocated additional c library types memory in order to make them work. Kinda oversomething solution for me.

Did anybody do something like this? What might be significant drawbacks here?

Artsiom Miksiuk
  • 3,896
  • 9
  • 33
  • 49
  • very related: https://stackoverflow.com/questions/22095214/how-to-use-unique-ptr-with-data-allocated-within-a-c-library – NathanOliver Feb 22 '23 at 16:10
  • Not an answer, just a suggestion: I found this talk to be very helpful for the same problems you describe https://www.youtube.com/watch?v=3ZO0V4Prefc - Not all the suggestions there apply 100% of the time, but they are always helpful to keep in mind (even when my "wrapper" consists only of a unique_ptr with a custom deleter). – StoryTeller - Unslander Monica Feb 22 '23 at 16:20
  • Don't forget rule of 3/5/0 for your wrapper (i.e as minima, `=delete` for copy assignment/constructor) – Jarod42 Feb 22 '23 at 16:20
  • encapsulation is not the holy grail ;). Consider `std::vector::data`, `std::string::data` and others. Sometimes its not a class purpose to hide its internals from the user, but rather the opposite. – 463035818_is_not_an_ai Feb 22 '23 at 16:34
  • You mention you can't use smart pointers, but I would reconsider. Look into `std::unique_ptr`'s customizable Deleter parameter. – DXPower Feb 22 '23 at 16:50
  • There's nothing wrong with this approach, as long as the calling code knows not to try to manually free the resources pointed to by the return value of the `CLibraryPointerType()` method. – Jeremy Friesner Feb 22 '23 at 18:37

0 Answers0