CppCon 2014: Stefanus DuToit "Hourglass Interfaces for C++ APIs"
Why Stack Overflow recommends it
Stack Overflow users link it when answering questions about shipping C++ libraries or DLLs, avoiding ABI incompatibilities, and exposing a clean C boundary with a C++ API on top.
Recommended by 4 people across 3 different months, 2014 to 2019.
What it is
A CppCon 2014 talk by Stefanus du Toit of Thalmic Labs on the Hourglass pattern for structuring C++ libraries. A stable C89 binary interface sits in the middle, with a header-only C++ wrapper on top and the C++ implementation underneath. It covers implementation techniques for C++98 and C++11 and lessons from real projects.
What people said
Strong rec Zarian · 2015-10 · Stack Overflow · on “How to pass vector<T> between library/module boundary using hourglass pattern?”
The question is related to a talk by Stefanus Du Toit on hourglass pattern. Its a great talk, really helpful for library writers. Youtube Link: [this video] Slideshare Link: [LINK] Ok here is the question: Say I have to pass a std::vector<MyObject> across the library boundary. What is the best way to do this using hourglass pattern. I am concerned about the performance as well as keeping a clean interface. Given below is a set of example interfaces that I want to implement. Clientside C++ interface: void MyLibraryClass::DoSomething(const std::vector<MyObject>& objs); C Interface: ???? (Not sure what is the best practice here) Internall library C++ interface: MyInternalLibraryClass::DoSomething(co
Recommends Mikael Persson · 2015-04 · Stack Overflow · on “How to use a vector of unique pointers in a dll exported class with Visual Studio”
I agree with Ben. If you want to have the benefits of DLLs, you need to export only a C API (or, see the classic "hourglass interface" presented at CppCon 2014 [this video] ). Otherwise, just use static linking (.lib / .a files). Dealing with C++ ABI issues when distributing / reusing DLLs is such a nightmare that their advantages pale in comparison.
Recommends mattnewport · 2015-04 · Stack Overflow · on “Shipping a C++ dll with only a C api exposed”
You might find this talk interesting on "Hourglass Interfaces for C++ APIs" which discusses issues around building a pure C API over a C++ library with C++ helper classes that sit on top as a header only API wrapper: [this video]
Recommends Vasiliy Galkin · 2017-07 · Stack Overflow · on “Visual Studio linker error when template class meets __declspec(import)”
Visual Studio support team triaged this issue, and as a result they filed a bug. Investigation is ongoing, details can be seen on Visual Studio forum [LINK] . I'll update this answer once I get further feedback from them. P.S. : Whether this will be recognized as a linker bug or not, I'd like to state that exporting complex C++ interfaces from DLL's is not really a good practice in general. Unfortunately I cannot change it in the codebase I'm working with. Personally, for architecture based on DLL plugins I would recommend either using some marshalling layer (like COM) or explicitly design interfaces according to "Hourglass principle". Here is a great talk from CppCon 2014 [this video] that expla
Cites sehe · 2014-11 · Stack Overflow · on “What does it mean when Boost.Exception symbols show up in 'nm' output? Will they cause ODR violations?”
If the code doesn't mix (e.g. if you adhere to the ** "Hourglass API interfaces" [this video] ** guidelines) there is no issue. Consider this: at worst you'd get duplicate symbol errors/warnings from the linker, right? I guess there's a reason why these symbols are _weak_.
Cites dyp · 2015-01 · Stack Overflow · on “Designing the instantiation and destruction of a class using the pimpl idiom”
This is almost a Code Review question now, so you might want to consider posting this on CodeReview.SE [LINK] . Also, it might not fit well to StackOverflow's philosophy of specific questions with specific answers, no discussion . I'll try to present an alternative nevertheless. Analysis and critique of (details of) the OP's approach Entry(EntryImpl* impl) : m_Impl(impl) { } // 2. Public destructor ~Entry() { delete m_Impl; } As the OP has already stated, neither of those functions should be called by the user of the library. The destructor invokes Undefined Behaviour if EntryImpl has a non-trivial destructor, for example. In my opinion, there's not much benefit to preventing users from cons
Cites Johann Gerell · 2015-10 · Stack Overflow · on “Call method from Class in DLL without exposing Class”
You have several options at your disposal. I'll present here 2 options where the client of your DLL has full control of the lifetime of the MyClass instance that it uses, although the client doesn't know it's actually a MyClass instance. Assuming your DLL-exposed feature is publicly known as Flubber . The first option is that you deliver your DLL with a public header file Flubber.h containing this: #ifdef FLUBBER_EXPORTS #define FLUBBER_API __declspec(dllexport) #else #define FLUBBER_API __declspec(dllimport) #endif typedef struct FlubberHandle_* FlubberHandle; FLUBBER_API FlubberHandle CreateFlubber(); FLUBBER_API void DestroyFlubber(FlubberHandle flubber); FLUBBER_API void SetFlubberNumber
Cites ComicSansMS · 2016-05 · Stack Overflow · on “CMake and different versions of Visual Studio”
This is not a Visual Studio specific problem. In general, C++ does not guarantee that a library built with one version of a compiler will work with an executable built by a different version of the same compiler, or by a different compiler. This is because C++ gives compilers certain freedoms in how to generate the binary layout of its objects. This is a very old problem and there is no easy solution. If you don't want to accept any restrictions on the library's interface, you will need to rebuild the library for every supported compiler version with a breaking ABI change (which usually means a separate build for every compiler and major version bump in the compiler version). CMake cannot do
Cites mooware · 2016-09 · Stack Overflow · on “How to program an interchangeable library?”
Look up "ABI compatibility". The Qt/KDE projects have a good guide about that: [LINK] [LINK] The extreme version of that would be the "Hourglass Interface" pattern, where the binary interface of the library is pure C, but there's an inlined C++ API above it and a C++ implementation below: [this video] EDIT: Just wanted to add a clarification: Where these guides talk about compatibility between different versions, your libraries would have to adhere to the same restrictions for different backends.
Cites Mr.C64 · 2016-10 · Stack Overflow · on “Sharing a C++ DLL and H file with customer”
@Charles: You can just browse the ATL/WTL headers :) But what matters is the concept. Moreover, I heard of this CppCon 2014 presentation on the _"hourglass model"_ [this video] that could come in handy for you; but I haven't watched it.