I am making a C++ wrapper around a C library. Let's say that the library (let's call it Clib) defines a function like this:
// clib.h
const char* clib_foo(clib_obj_t* obj);
In my wrapper I have the following:
// clibpp.h
#include <clib.h>
namespace clib {
std::string_view foo(const clib::obj_t& obj) {
return clib_foo(obj.raw());
};
}
// symbols from both clib.h and clibpp.h visible
Now, my wrapper is header only. So when someone includes clibpp.h they see symbols from both clibpp.h and clib.h. I want to avoid that. my idea is to include the clib.h header inside a namespace in the clibpp.h header to hide all the symbols.
// clibpp.h
namespace clib {
namespace detail {
#include <clib.h>
}
std::string_view foo(const clib::obj_t& obj) {
return detail::clib_foo(obj.raw());
};
}
// symbols from only clibpp.h visible (apart from preprocessor definitions)
Is this a good idea or possible to do? Why doesn't anybody seem to do it?
Is this a good idea or possible to do?
No, that won't work because the C library - for obvious reasons - doesn't define the functions etc. within that namespace.
Why doesn't anybody seem to do it?
Because it doesn't work.
If you give up the desire to have a header-only wrapper library, then you can avoid "leaking" the C header since you could include it only within a translation unit of the wrapper library.
Note that this still doesn't solve all problems with name clashes since One Definition Rule applies across translation unit boundaries. If you link with a C library, then the external names of that library cannot be used by anything else. Hiding the C header does prevent macro-pollution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With