4

I have a library implemented in C++ which has a C interface. This C interface is, for all intents and purposes, the only way to use this library. C++11 seems to discourage the use of raw pointers but neither shared_ptr or unique_ptr are suitable in this case. From what I understand, intrusive_ptr is an option, but I am both unsure of how this differs from maintaining my own ref count (I am new to C++) and wary of wading into boost yet (I am new to C++).

How should I handle memory management in C++11 and higher? I only state the spec to make it clear that I am willing to use the features of the latest spec and have no need to maintain compatibility with older specs.

asked Apr 19, 2014 at 4:01
2
  • Why aren't unique or shared pointers suitable here? Unique and shared pointer between them should cover virtually every need you have, except when it comes to actually defining the C-compatible functions in which case owning raw pointers is necessary. Commented Apr 19, 2014 at 7:51
  • 1
    @DeadMG: that would have required the C code passing around raw pointers to shared_ptr<T> alike, which would have been opaque to the C code. How do you decipher an opaque address from a debugger? Commented Apr 19, 2014 at 8:02

2 Answers 2

2

The fact that C++11 offers a range of smart-pointer classes to make life easier with memory management does not mean that you can't or shouldn't use raw pointers where that is appropriate.

The committee that maintains the C++ standard is very reluctant to remove existing features from the language and more so if it is a widely used and useful feature like raw pointers. Keeping the language backwards compatible is one of the corner stones in its evolution.

With that said, if you have to provide a C-compatible interface to your C++ library, you should use only features from the common subset of C and C++ in your interface and that means using raw pointers where they are visible in the interface and effectively letting the user of your library deal with allocation/deallocation (although you can provide functions for that).

answered Apr 19, 2014 at 6:31
4
  • If the library keeps ownership of a resource it would be fine to use smart pointers internally within the library and return raw pointers in the interface, no? Commented Apr 19, 2014 at 7:46
  • 2
    @ChrisDrew: You are correct. The trickiness arise when these raw pointers are jointly owned (shared) by both the C caller and some other C++ objects in the library. Commented Apr 19, 2014 at 8:06
  • @rwong, Yes, or if you want to safely transfer ownership from client to library, or vice versa. Commented Apr 19, 2014 at 8:10
  • @ChrisDrew: Yes, you can use smart-pointers internally. You just have to be very aware that when such a pointer crosses the interface, you are giving out an untracked reference. You must double check that the smart pointer doesn't clean up the resource too early. Commented Apr 19, 2014 at 14:30
1

Analysis.

It has to use some kind of intrusive pointer (specifically user-implemented reference counting), though it could be Boost intrusive_ptr or some other flavor.


My personal opinion.

I have used Microsoft COM pointers in my projects and it works fine. If your code only has to work on Microsoft Windows, this may be the recommended route as the C systems programmer for Windows will probably be familiar with it. For all other considerations, including cross-platform applications, use Boost intrusive_ptr.

I have described my opinions about the minimal usage of Microsoft COM pointers in this answer.


The nature of intrusive_ptr.

It is important to understand the nature of intrusive_ptr. It is a handle class, implemented using C++ template. It is provided so that such objects can be owned by C++ callers.

C code cannot see this handle class from their header includes, let along call its methods. Instead, the C code would be calling some extern "C" methods. This means you will be providing extern "C" methods which in turn call the intrusive_ptr_add_ref and intrusive_ptr_release methods provided by Boost intrusive_ptr.

http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/intrusive_ptr.html


What this means.

Calling C++ methods on this object from C code will require one wrapper function per class method, such as this.

For objects that require add_ref and release management, you will provide extern "C" wrapper functions for those as well.

It is your responsibility to document in an obvious way, or convey to the C programmer, what pointer types in your object are reference-counted. A combination of naming convention, API documentation, API usage sample, and verbal warning is recommended.

Finally, understand the laws (object ownership rules) that needs to be obeyed when using reference counting. See this question and the answer.


Advanced topics - object or interface type cast, interface query, interface segregation

I have only used these techniques with Microsoft COM (via its QueryInterface method), so I cannot comment on whether one could use these techniques on Boost intrusive_ptr when programming via an extern "C" interface.

answered Apr 19, 2014 at 7:40

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.