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"
}
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
Related
Is it possible to "link" a static library, instead of just combining its .obj files into the .lib?
I have static library (A) which depends on Version 1 of static library B (B.1). I link A into my Executable. The executable itself depends on Version 2 of static library B (B.2). When the executable is created, the Linker complains about multiple defined symbols coming from B.1 (via A) and B.2. It is not desirable to solve this by setting /FORCE:MULTIPLE.
Why is it not possible in this case to basically "treat a static library like a DLL" in some sense?
If A would be a DLL, and linked into the executable by using its Import-Lib, everything would work out. In the resulting process, and after the Loader loaded DLL A into the process space, the definitions of B.1 (coming via the DLL) and B.2 (coming from the Image file of the Executable) would coexist just fine.
Why can the static library A not be "linked" so it would allow this coexistence as well? -Resolving all references and make them fixed in A. Or maybe marking everything what A imports from B.1 somehow as "private", so the Linker, which creates the Executable, treats all B.1 parts as internals of A, which he has nothing to do with? Hench, "embedding" A (compiled as a DLL) into the Executable?
Why can the static library A not be "linked" ... ?
because libraries are not executables (a DLL is).
So generally you cannot combine two versions of a library into one executable when there are conflicting names in both of them.
To circumvent this you could use namespaces with optionally an inline namespace for the prefered version (which can be controlled by conditional compilation ,one condition for the executable and one for the depending library). But be carefull with such strategy !
namespace libB
{
// "forward" declare namespaces
#ifdef LIB_A
inline namespace v1 {}
namespace v2 {} // not really necessary here
#else
namespace v1 {} // not really necessary here
inline namespace v2 {}
#endif
namespace v1
{ // implementation of version1
}
namespace v2
{ // implementation of version2
}
}
let's assume I do simple function designed to be exported as DLL
#include <iostream>
__declspec(dllexport) std::string __cdecl Hello(){
return std::string("Hello world");
}
This dll is intended to be used with a program already using iostream so is it possible to do the same thing but don't include iostream ? (Maybe it's a stupid question)
If yes, how can I specify it to my compiler? (Mingw)
Each DLL would need to pass preprocessing, compilation and linking phase. DLL is the same as any other type of project (except static library). Hence, it needs all #includes, library files, and all symbols fully resolved.
If DLL need to use iostream, or any STL class for that matter - the respective code must #include appropriate header.
Each source file that uses a standard library facility needs a corresponding #include directive. It doesn't matter whether the file is built into a DLL or not.
Your file does not use any iostreams facilities, but it does use strings, so #include <string> is mandatory. If you omit #include <string> but include some other standard header, it may or may not work.
I have a source code of some library. There is a function that is only declared (in a header file), but not defined in the source code.
extern "C" {
extern int theFunc(int);
}
What is the reason to have only a declaration of a function in a library?
In addition of Mike Kinghan's answer (which covers most of the cases), there is also a (rather unusual) reason to declare in the library header file a function not implemented in that library. Sometimes, that library expects a plugin and the user is expected to provide such a plugin (in some way, perhaps passing the plugin file name to some other function). The library would use dynamic loading techniques (such as dlopen(3) on Linux) to install such a plugin. And it would fetch some particular function (with dlsym(3) on Linux) from the plugin. Then it makes sense to declare, but not define such a plugin function, in the library headers.
I do admit that this case is unusual and contrived.
For a concrete example, read about GCC plugins. Your plugin should #include "gcc-plugin.h" which indirectly declares
/* Declaration for "plugin_init" function so that it doesn't need to be
duplicated in every plugin. */
extern int plugin_init (struct plugin_name_args *plugin_info,
struct plugin_gcc_version *version);
but that plugin_init should be defined by your plugin code. Then GCC would dlopen your plugin, using something equivalent to
void*plhdl = dlopen("/home/you/yourplugin.so", RTLD_NOW);
and later get a function pointer using
typeof(plugin_init)* funptr = dlsym(plhdl, "plugin_init");
Notice that the symbol plugin_init does not appear in the code segment of GCC.
Another example is the Qt framework (a set of libraries). Read about Qt plugins.
My project uses a third party modules where one of the header file has defined 'errc'
typedef int errc;
I want to use STL in project but when I add stl header file I get name conflict for errc since its class name in the standard library.
error C2872: 'errc' : ambiguous symbol
I don't really want to change the third party module, is there any way I can come around this problem and work with the standard library in the project?
Don't use in the file
using namespace std;
But you can still include it into functions, say
void f()
{
using namespace std;
cout<<endl;
}
I am using a C library (libgretl) from C++ and some of its functions conflict with my code, so I wanted to wrap it in a namespace, like this:
namespace libgretl {
extern "C" {
#include <gretl/libgretl.h>
}}
However, this does not compile, I get "undefined" errors from gcc files (using mingw32 with gcc 4.5.2 on Windows).
The first errors come from the following code block of file c++/cstddef:
_GLIBCXX_BEGIN_NAMESPACE(std)
using ::ptrdiff_t;
using ::size_t;
_GLIBCXX_END_NAMESPACE
where the macros expand respectively to namespace std { and }. There are more errors after these.
Omitting the extern "C" directive does not help. Using an anonymous namespace reduces the amount of errors, but it still won't compile.
My question is therefore if there is some way to include such a C library and place its functions into a namespace, without changing the gcc or the library's source files?
Thanks.
Michal
You can't do it. Namespaces are not just source code decorations, they are mangled to object symbols by compiler.
Native C function foo() in library will be available by symbol _foo in object file, but calling bar::foo() will generate reference to, for example, #N3barfoo. As result, linker error will occur.
You may create "proxy" functions in separate source file, including original library header only in this source and putting all proxy functions to namespace.
You don't get to simply wrap a namespace around an external declaration and have it appear within that namespace... the item (function, global) must have been built within that namespace from the start. Since C doesn't support namespace resolution, this could not have been the case.
You need to change your own code to accommodate this library, unless you're willing to chante the library itself.
In order to refer to a non-namespace'd item that conflicts with your own namespace'd item, refer to ::item().
I guess the C library was compiled as C, which means namespaces are not included and not supported in the compiled code. Thus, your compiled C library cannot be in a namespace. Altering the header by encapsulating the include will not change that.
You can still encapsulate your own code in a namespace.