开发者

wrapper around API using reference counting logic C++

开发者 https://www.devze.com 2023-02-20 00:34 出处:网络
I am going to use heavily some C-API in my C++ application, I have a lot of functions available that I need to call in couple. For example createFoo(void*) at the beginning and freeFoo(void*) when the

I am going to use heavily some C-API in my C++ application, I have a lot of functions available that I need to call in couple. For example createFoo(void*) at the beginning and freeFoo(void*) when the job is done.

So, I thought to use the RAII idiom, so I created the first开发者_运维百科 wrapper with copy constructor and assignment operator private and not implemented. It works fine, however I would like a richer copy semantic. I would like to use a reference counting copy semantic. I have considered to write my own version but I don't want reinvent the wheel. Also the boost::shared_ptr is already implementing pretty much the behave that I want to achieve.

The only difference is the pointer is not create with new and it is not release with delete. I would like to customize the source and the sink functions.

I have the feeling that is a good way to face the problem, however I cannot come up with a class that implement my idea.

Here are the questions, do you think it is a good way to solve my problem? Is there any open source code that implement something similar? Do you have any hints?

Thanks


It's really easy. As an example, suppose you have the C fopen interface:

FILE* fopen(blah);
int fclose(FILE*);

Then you can wrap FILE resource with shared_ptr like this:

shared_ptr<FILE> ptr(fopen("file.txt", "rt"), fclose);
// use the file pointed by ptr
fwrite(..., ptr.get());

// FILE is automatically closed by a call to fclose when 
// reference count drops to zero...

Edit: Let me explain a bit.shared_ptr stores a 'deleter' along with the reference counters for ownership and weak ownership. A deleter is any object that can be called with the pointer to the resource to be freed as an argument. The default deleter simply calls delete on its argument, however you can pass your own deleter.

When I apply the technique above, I usually wrap the creation into a separate function. This simplifies the code and allows me to check for error-codes returned from C-style APIs and convert them to exception:

shared_ptr<FILE> MakeFile(const char* name, const char* mod)
{
    if(FILE *ptr = fopen(name, mod))
        return shared_ptr<FILE>(ptr, fclose);

    throw SomeExceptionType("fopen", errno, ...);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消