16

I am trying to link to an external library, on which I have no control, that doesn't have any namespace for its functions.

Since I don't want to have conflicts with the names defined in that library: how to include the external headers in a namespace that I would create myself?

I know that the following code doesn't work, but the spirit of the question is there:

namespace extLib {
  #include "externalFolder/externalHeader.h"
}
10
  • 2
    What do you mean "doesn't work"? Commented Aug 8, 2018 at 15:21
  • 3
    @SombreroChicken If it's not a header-only library, including the headers into the wrong namespace will "promise" to the linker that certain symbols will exist in that namespace that it won't find there. Think of mangled names. Commented Aug 8, 2018 at 15:22
  • 3
    It is not supposed to work because that library does not export names from whatever namespace you include it's header into. Commented Aug 8, 2018 at 15:22
  • 2
    There is nothing in C++ like this (probably the hyped modules TS could solve that, with some syntax to import declarations under a namespace). If you are really concerned about conflicts, the usual approach is to wrap the 3rd party API with you functions under your own namespace, etc. Commented Aug 8, 2018 at 15:32
  • 2
    @WhozCraig I don't like having arbitrary identifiers taken away from me (or worse, malfunctioning). There is a reason why namespaces exist, and dismissing a desire to isolate code into appropriate namespaces should not be met with "just don't produce any conflicts" - we wouldn't need namespaces then. Commented Aug 8, 2018 at 15:36

1 Answer 1

14

If you are working with a header-only library, your mentioned approach will probably work. At least I can't think of any issue right away.

But if you have a compiled library that you have to link to, there is no way to put the library functions themselves into their own namespace (at least not without recompiling your own version of said library). That's because in the .dll or .so or what have you, each function has a mangled name that includes all namespaces (example). When you eventually link against the library, you can only "reach" those functions under that exact mangled name, which requires that your function calls are against that same (or, in your case, no) namespace as the compiled versions.

The "classic" workaround is to write a thin wrapper around the library, where for every exposed function, you do:

wrapper.h:

namespace libraryWrapper
{
  void bar(int);
}

wrapper.cpp

#include "realLibrary.h" // Defines bar(int)

void libraryWrapper::bar(int x)
{
  ::bar(x)
}

Basic example

Sign up to request clarification or add additional context in comments.

6 Comments

Sans-header only situations, this is by far the most common method I've used in the past for this. Important to note, to avoid identifier conflicts at link time, said-wrapper will have to be in its own isolated module (a DLL, a .so, choose your poison), exposing only the now-namespace-wrapped functions. If link-time conflicts are the problem, be prepared for that.
Another possible solution, but only for c library is described here: stackoverflow.com/questions/4350756/…
@WhozCraig Makes sense. I guess you can avoid this need by having all your own code within namespaces though (anonymous ones if need be), although I don't know if there might be a reason that you can't do that. Well, I suppose if you have two such abhorrent namespace-free libraries they might conflict. *shudder*
@MaxLanghof Heh, sure. If you can't namespace the third-party code, namespace everything else. Yeah, that would work, but whoa man. Regarding anonymous namespaces, for static per-module stuff, you're nuts not to use them. I cannot do justice to describe just how much pollution I've cleaned out of the global namespace from years of technical debt and just-put-that-unnecessary-global-there practices in the code I work inherit at work. And they still do it even after being told not to. Almost can't keep up. Anyway, good answer.
It doesn't even work for any header-only library that includes a standard library header.
|

Your Answer

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.