Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapping C create and destroy functions using a smart pointer

I have some C API that handles object creation and destruction, it provides: createObject(...) and destroy(...). I want to wrap it into some more modern construction/destruction mechanisms and use them with smart pointers. I am afraid that at some point I will forget to destroy the object, or some exception will occur.

I am aware of custom deleter function for shared_ptr, but I can't explicitly call new, because createOjbect function handles initialization.

Can I use STL smart pointers in this situation? Do I have to, from scratch, implement a class with initialization in constructor, destruction in destructor and reference counting in this situation?

like image 345
Piotr Barejko Avatar asked Aug 26 '17 07:08

Piotr Barejko


People also ask

Do we need to delete a smart pointer in C++?

So, we don’t need to delete it as Smart Pointer does will handle it. A Smart Pointer is a wrapper class over a pointer with an operator like * and -> overloaded. The objects of the smart pointer class look like normal pointers. But, unlike Normal Pointers it can deallocate and free destroyed object memory.

How do you wrap interface pointers in COM objects?

When you work with COM objects, wrap the interface pointers in an appropriate smart pointer type. The Active Template Library (ATL) defines several smart pointers for various purposes. You can also use the _com_ptr_t smart pointer type, which the compiler uses when it creates wrapper classes from .tlb files.

What is the use of wrapper in C++?

The wrapper is C++ but exposes itself as C. Meaning the exposed C functions are C functions. However, this needs to be compiled as C++ in order to use new and delete for proper C++ class initialization. The wrapper creates a struct and puts the CPPMather object into it as as void pointer. This struct allows us to use it in a type safe manner in C.

What is smart pointer in C++11?

C++11 comes up with its own mechanism that’s Smart Pointer. When the object is destroyed it frees the memory as well. So, we don’t need to delete it as Smart Pointer does will handle it. A Smart Pointer is a wrapper class over a pointer with an operator like * and -> overloaded.


1 Answers

The std::shared_ptr is fully capable to create and delete an object with cutstom creator and deleter, but instead of new you have to use the creator function.

Let's consider, we have the following creator and deleter:

typedef struct {
    int m_int;
    double m_double;
} Foo;

Foo* createObject(int i_val, double d_val) {
    Foo* output = (Foo*)malloc(sizeof(Foo));

    output->m_int = i_val;
    output->m_double = d_val;

    puts("Foo created.");
    return output;
}

void destroy(Foo* obj) {
    free(obj);
    puts("Foo destroyed.");        
}

To manage an instance of Foo created by functions above, simply do the following:

std::shared_ptr<Foo> foo(createObject(32, 3.14), destroy);

Using the std::shared_ptr is an overhead if you don't wish to share the object's ownership. In this case the std::unique_ptr is much better but for this type you have to define a custom deleter functor with which it can delete the managed Foo instance:

struct FooDeleter {
    void operator()(Foo* p) const {
        destroy(p);
    }
};
using FooWrapper = std::unique_ptr<Foo, FooDeleter>;

/* ... */

FooWrapper foo(createObject(32, 3.14));
like image 189
Akira Avatar answered Oct 20 '22 01:10

Akira