I have a static library and it has a class like below in its header file:
namespace MyNameSpace
{
class MyClass
{
public:
void Something();
};
}
I linked above static library with my another dynamic link library project, and now I can call above function like below:
int Main()
{
MyNameSpace::MyClass A;
A.Something();
}
Although above works fine, I like to use my static library function like below, instead declaring classes:
int Main()
{
MyNameSpace::Something();
}
But I am wondering about the correct way to do this.
I tried it in static library like:
namespace MyNameSpace
{
void Something();
}
and after linking static library to the dynamic library, tried to use the function in it like:
MyNameSpace::Something();
But, IntelliSense doesn't see it and I already included my static library's header file and linked it properly.
What I want to do is declare a function in a static library outside classes and make it visible to another projects whose it linked into. In this case, to dynamic library.
Thanks in Advance.
I was finally able to do what I want by declaring the function like below:
In Static Library:
namespace MyNameSpace
{
void Something();
}
In Dynamic Link Library:
MeNameSpace::Something();
Now the function is visible even outside file scope.
Related
I am developing a project in which I have a vendor library, say vendor.h, for the specific Arduino-compatible board I'm using which defines class HTTPClient that conflicts with an Arduino system library, HTTPClient.h, which also defines class HTTPClient.
These two classes are unrelated other than having the same name, and the vendor implementation of an HTTP client is far less capable than the Arduino system library's implementation, so I'd prefer to use the latter. But I can't omit including the former, because I need quite a bit from the vendor.h. Essentially, I have the problem posed here, but with classes rather than functions. I have the full code of both, but given that one is a system library and the other is a vendor library, I'm reluctant to fork and edit either, as that adds lots of merging work down the road if either of them are updated, so my preference would be to find a tidy solution that doesn't edit either header.
I've tried a variety of solutions posted in other SO questions:
I do not want to leave out either header, as I need vendor.h for quite a few things and need the capabilities of HTTPClient.h's client implementation
Proper namespaces in the headers would solve the problem, I would prefer to avoid editing either header
I tried wrapping the #include <HTTPClient.h> in a namespace in my main.cpp, but that caused linking errors, as it's not a header-only library, so the header & cpp weren't in the same namespace
I tried a simple wrapper as proposed for the function in the above linked SO question in which the header contained just a forward declaration of my wrapper class & the associated cpp contained the actual class definition. This gave a compiler error of error: aggregate 'HTTP::Client client' has incomplete type and cannot be defined (Code sample of this attempt below)
main.cpp:
#include <vendor.h>
#include "httpclientwrapper.h"
HTTP::Client client;
httpclientwrapper.h:
#ifndef INC_HTTPCLIENTWRAPPER_H
#define INC_HTTPCLIENTWRAPPER_H
namespace HTTP {
class Client;
}
#endif
httpclientwrapper.cpp:
#include "httpclientwrapper.h"
#include <HTTPClient.h>
namespace HTTP {
class Client : public ::HTTPClient {};
}
In that example, I can't inherit from HTTPClient in a class definition in my header, as that will reintroduce the duplicate class name to the global namespace in my main program (hence the perhaps misguided attempt to see if a forward declaration would do the trick). I suspect that I can resolve the issue by completely duplicating the class definition of HTTPClient in my wrapper class above rather than trying to use inheritance. I would then add member definitions to my wrapper cpp which pass the call to HTTPClient's members. Before I go through the trouble of rewriting (or more likely, copy/pasting) the entire HTTPClient definition from HTTPClient.h into my own wrapper, I was wondering if there was a better or more proper way to resolve the conflict?
Thanks for you help!
As a solution was never proposed, I'm posting an answer that summarizes my research and my ultimate resolution. Mostly, I encourage the use of namespaces, because proper uses of namespaces would have eliminated the conflict. However, Arduino environments try to keep things simple to lower the barrier of entry, eschewing "complicated" features of C++, so more advanced use cases will likely continue to run into issues like this. From other SO answers and forum posts (cited where I could), here are some methods for avoiding name conflicts like this:
If you can edit the source
Edit the source code to remove the conflict or add a namespace to one of both libraries. If this is an open source library, submit a pull request. This is the cleanest solution. However, if you can't push your changes back upstream (such as when one is a system library for some hardware), you may end up with merge issues down the road when the maintainer/developer updates the libraries.
If you can't edit the source
Credit for part of this: How to avoid variable/function conflicts from two libraries in C++
For libraries that are header only libraries (or all functions are inline)
(ie, they have only a .h file without a .o or .cpp)
Include the library inside a namespace. In most code, this is frowned upon as poor form, but if you're already in a situation where you are trying to cope with a library that doesn't contain itself nicely, it's a clean and simple way to contain the code in a namespace and avoid name conflicts.
main.cpp
namespace foo {
#include library.h
}
int main() {
foo::bar(1);
}
For libraries with functions
The above method will fail to link at compile time, because the declarations in the header will be inside the namespace, but the definitions of those functions are not.
Instead, create a wrapper header and implementation file. In the header, declare your namespace and functions you wish to use, but do not import the original library. In the implementation file, import your library, and use the functions inside your new namespaced functions. That way, the one conflicting library is not imported into the same place as the other.
wrapper.h
namespace foo {
int bar(int a);
}
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
int bar(int a) {
return ::bar(a);
}
}
main.cpp
#include "wrapper.h"
int main() {
foo::bar(1);
}
You could also, for the sake of consistency, wrap both libraries so they're each in their own namespace. This method does mean that you will have to put in the effort to write a wrapper for every function you plan to use. This gets more complicated, however, when you need to use classes from the library (see below).
For libraries with classes
This is an extension of the wrapper function model from above, but you will need to put in more work, and there are a few more drawbacks. You can't write a class that inherits from the library's class, as that would require importing the original library in your wrapper header prior to defining your class, so you must write a complete wrapper class. You also cannot have a private member of your class of the type from the original class that you can delegate calls to for the same reason. The attempt at using a forward declaration I described in my question also did not work, as the header file needs a complete declaration of the class to compile. This left me the below implementation, which only works in the cases of a singleton (which was my use case anyway).
The wrapper header file should almost completely duplicate the public interface of the class you want to use.
wrapper.h
namespace foo {
Class Bar() {
public:
void f(int a);
bool g(char* b, int c, bool d);
char* h();
};
}
The wrapper implementation file then creates an instance and passes the calls along.
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
::Bar obj;
void Bar::f(int a) {
return obj.f(a);
}
bool Bar::g(char* b, int c, bool d) {
return obj.g(b, c, d);
}
char* Bar::h() {
return obj.h();
}
}
The main file will interact with only a single instance of the original class, no matter how many times your wrapper class in instantiated.
main.cpp
#include "wrapper.h"
int main() {
foo::Bar obj;
obj.f(1);
obj.g("hello",5,true);
obj.h();
}
Overall, this strikes me as a flawed solution. To fully wrap this class, I think the this could be modified to add a factory class that would be fully contained inside the wrapper implementation file. This class would instantiate the original library class every time your wrapper class is instantiated, and then track these instances. In this way, your wrapper class could keep an index to its associated instance in the factory and bypass the need to have that instance as its own private member. This seemed like a significant amount of work, and I did not attempt to do so, but would look something like the code below. (This probably needs some polish and a real look at its memory usage!)
The wrapper header file adds a constructor & private member to store an instance id
wrapper.h
namespace foo {
Class Bar() {
public:
Bar();
void f(int a);
bool g(char* b, int c, bool d);
char* h();
private:
unsigned int instance;
};
}
The wrapper implementation file then adds a factory class to manage instances of the original library's class
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
class BarFactory {
public:
static unsigned int new() {
instances[count] = new ::Bar();
return count++;
}
static ::Bar* get(unsigned int i) {
return instances[i];
}
private:
BarFactory();
::Bar* instances[MAX_COUNT]
int count;
};
void Bar::Bar() {
instance = BarFactory.new();
}
void Bar::f(int a) {
return BarFactory.get(i)->f(a);
}
bool Bar::g(char* b, int c, bool d) {
return BarFactory.get(i)->g(b, c, d);
}
char* Bar::h() {
return BarFactory.get(i)->h();
}
}
The main file remains unchanged
main.cpp
#include "wrapper.h"
int main() {
foo::bar obj;
obj.f(1);
obj.g("hello",5,true);
obj.h();
}
If all of this seems like a lot of work, then you're thinking the same thing I did. I implemented the basic class wrapper, and realized it wasn't going to work for my use case. And given the hardware limitations of the Arduino, I ultimately decided that rather than add more code to be able to use the HTTPClient implementation in either library, I wrote my own HTTP implementation library in the end, and so used none of the above and saved several hundred kilobytes of memory. But I wanted to share here in case somebody else was looking to answer the same question!
I am converting a large Windows C++ application from a large set of source files to
a smaller core application linked to several static libraries (to which many
of the original source files are moved).
Each library requires access to a 'registration method' in the core application.
Each library should call that method during global initialization, but that is
not happening. That is my problem.
The code works fine in the original form where libraries are not used.
I guess I am omitting a necessary link option for the libraries, but
I don't know which.
I have created a minimal, workable example. I developed this
on Windows 10 using:
CMake 3.14.5
MSVC 2019
Here's CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.9)
project (CMakeLinkTest)
add_library(myLibrary STATIC MyStar.cpp)
add_executable(CMakeLinkTest StarFactory.cpp main.cpp)
target_link_libraries(CMakeLinkTest myLibrary)
The application contains main.cpp:
#include <iostream>
int main(int argc, char *argv[]){
std::cout << "Hello World!" << std::endl;
return 0;
}
and a singleton class called StarFactory.
StarFactory.h:
#include<string>
class StarFactory
{
public:
static StarFactory* instance();
~StarFactory() {};
std::string registerStarType(std::string a_type);
private:
StarFactory() {};
static StarFactory* mp_instance; // Singleton instance
};
StarFactory.cpp:
#include <iostream>
#include "StarFactory.h"
StarFactory* StarFactory::mp_instance = 0;
StarFactory* StarFactory::instance()
{
if ( mp_instance==0 )
mp_instance = new StarFactory;
return mp_instance;
}
std::string StarFactory::registerStarType(std::string a_type)
{
std::cout << "registerStarType: " << a_type << std::endl;
return a_type;
}
Finally, a static library contains class MyStar which registers itself with
the singleton at global initialisation.
MyStar.cpp:
#include<string>
#include "StarFactory.h"
class MyStar
{
public:
MyStar() {
StarFactory* s = StarFactory::instance();
//s->registerStarType("MyStar");
};
};
MyStar myStar;
std::string starName = StarFactory::instance()->registerStarType("MyStar");
Now for what happens. If I link MyStar.cpp directly into the application I see:
>CMakeLinkTest.exe
registerStarType: MyStar
Hello World!
If link MyStar.cpp into MyLibrary.lib and link that to the application I see:
>CMakeLinkTest.exe
Hello World!
So, the library's call (last line of MyStar.cpp) to the application's singleton is not working.
Can anyone explain this please?
As stated by engf-010, if a symbol defined in your static library is not used, the linker won't put it in the final binary.
One way to solve the problem using CMake would be to use an OBJECT library instead of a STATIC library.
The default behavior for linker is to not include static library that is not referenced.
You can either:
force linker to include the library anyway - you can use cmake's add_link_options or equivalent
not use a static library - just link the object like as in your first example
reference the code in static library
use a shared object (dynamic library) instead
I build several libraries (static and dynamic ones) which all need to access a namespace containing namespace-global variables.
The functions for altering the variables are defined in one cpp file. If a function inside a library accesses one of those functions, it seems to create a local copy of the whole cpp file, including all variables (and maybe also functions). This means, every library accesses a variable at a different address, resultig in a mess, because the variables have to be shared by all libraries. How can I get around this?
The sourcecode, reduced to the essential:
//include.h
namespace myns {
extern int vars;
}
.
//include.cpp
#include <myns/include.h>
namespace myns {
int vars;
void MyClass::setVars(int var) {
vars = var;
}
}
.
//myclass.h
namespace myns {
class MyClass {
void setVars(int var);
}
}
.
//myclass.cpp.in
//This will be generated by CMake and then compiled into a library
#include <myns/#package#/myclass.h>
namespace myns {
namespace #package# {
class __declspec(dllexport) MySubclass : public MyClass {
MySubclass();
}
MySubclass::MySubclass() {
setVar(#value#);
}
}
}
using namespace myns;
extern "C" __declspec(dllexport) void exported_function() {
new MySubclass();
}
Everytime the exported_function() is called, the vars variable would have a different address. Why does that happen? I need all library functions to access the same vars variable!
Even though the language bears little resemblance to the alleged "C++", and even though the question is severely underspecified (what kind of libraries?), the problem is sufficiently well known that it's answerable.
In short, each Windows DLL has its own internal variables etc. (a Windows DLL is more akin to an executable than to a C++ library).
Note that standard C++ does not support dynamically loaded libraries except for a single cryptic little statement about global initialization order.
A solution is to put the shared state in its own DLL.
By the way, when you are providing setters and getters for a variable there is really little point in also making it directly accessible. That's asking for trouble. But then, using a global variable is, in the first place, also asking for trouble.
So I have a static library (MacOS, .a library). It's written in C++ and has static initializers in it's code like that:
//myclass.hpp
class MyClass {
...
static MyClass *defaultValue_;
static MyClass *newInitialDefaultValue();
...
}
...
//myclass.cpp
MyClass *MyClass::defaultValue_ = newInitialDefaultValue();
...
I'm linking my .dylib library against this .a lib. Unfortunately, when my .dylib file is loaded, no MyClass::newInitialDefaultValue() is get called.
What could be the reasons and how to deal with this?
I've tried -all_load and -force_load linker flags with no luck.
The all_load and force_load linker flags only ensure that the code is linked into the binary. I don't think these flags will help you.
The only guarantee that I think you can count on is that your initializer in myclass.cpp will be called before any other code in the same cpp file is called. You need to expose access to your default via a function. This would be similar to the Singleton pattern. For example:
//myclass.hpp
class MyClass {
...
static MyClass *getDefaultValue();
...
}
...
//myclass.cpp
static MyClass* defaultValue_; // Note that this is not a member variable
MyClass* MyClass::getDefaultValue() {
if (defaultValue_ == nullptr) {
defaultValue_ = newInitialDefaultValue();
}
return defaultValue_;
}
...
NOTE: I made no attempt to make this thread safe or handle errors.
Now, the defaultValue_ still will not be automatically initialized when the library is loaded. But since the only access callers have is through getDefaultValue(), it is guaranteed to be initialized when they access it.
This question already has answers here:
Closed 13 years ago.
Duplicate of the following question: C function conflict
Hi,
in my current project I have to use some kind of interface lib. The function names are given by this interface, what this functions do is developers choice. As far as I can tell a project shall use this functions and when it comes to compiling you choose the lib and with it the functionality. What I try to do is to use an existing lib and my lib at the same time by wrapping the other and call it in mein functions:
otherlib:
int function1 (int a) {
// do something
}
mylib:
int function1 (int a) {
//my code here
otherlib::function1(a);
}
Problem is I don't have access to the other lib and the other lib doesn't have any namespaces. I already tried
namespace old {
#include "otherlib.h"
}
and then call the old function by old::function1 in my function. This works as long as it's only header file. The lib exports it's symbol back into global space. Also something like
namespace new {
function1 (int a) {
::function1(a);
}
}
didn't work. Last but not least I tried ifdefs and defines suggested here
but I wasn't successful.
Any ideas how to solve this? Thanks in advance.
EDIT: I neither have access to the old lib nor the project both libs shall be used in.
EDIT2: at least the old lib is a static one
Namespaces in C solved using library names prefixes like:
libfoo --> foo_function1
libbar --> bar_function1
These prefixes are actual namespaces. so if you write libbar
int bar_function1(int a) {
function1(a);
}
This is the way to solve problems.
C has namespaces --- they just called prefixes ;)
Another option is to do various dirty tricks with dynamic loading of libraries like:
h1=dlopen("libfoo.so")
foo_function1=dlsym(h1,"function1")
h2=dlopen("libbar.so")
bar_function1=dlsym(h2,"function1")
It seems as if the other lib is C and your code is C++. You can be running into a mangling problem (C++ compilers mangle the symbols -- add extra stuff in the symbol name do differentiate overloads and the like).
If the library is pure C you can try:
extern "C" { // disable mangling of symbol names in the block
#include "otherlib.h"
}
namespace new_lib { // new is a reserved word
int function1( int a ) {
::function1(a);
}
}
I have not tried it. Also consider providing the error messages you are getting.
Another option would be (if the library is dynamic) dynamically loading the lib and calling the function. In linux (I don't know about windows) you can use dlopen to open the library, dlsym to obtain the symbol and call it:
// off the top of my head, not tried:
int function1( int a )
{
int (*f)(int); // define the function pointer
void * handle = dlopen( "library.so" );
f = dlsym( handle, "function1" );
f( a ); // calls function1(a) in the dynamic library
}
In this case, as you are not linking against the library you won't get a symbol conflict, but then again, it is only valid for dynamic libraries and it is quite cumbersome for regular usage.
UPDATE
If your users will not use 'otherlib' directly (they won't include their headers) and they will be only C++, then the first approach could be possible (even if horrible to read):
// newlib.h
namespace hideout {
int f( int a );
}
using namespace hideout; // usually I would not put this on the header
// newlib.cpp
extern "C" { // if otherlib is C, else remove this line
#include "otherlib.h"
}
namespace hideout {
int f( int a ) { return ::f( a*2 ); }
}
// main.cpp
#include "newlib.h"
int main()
{
std::cout << f( 5 ) << std::endl;
}
How does it work? User code will only see a declaration of function1 (in the example f()) as they are not including otherlib.h. Inside your compilation unit you see the two declarations but you differentiate through the use of the namespace. The using statement in the header does not bother you as you are fully qualifying in your cpp. The user main.cpp will include only your header, so the compiler will only see hideout::f, and will see it anywhere due to the using statement. The linker will have no problem as the C++ symbol is mangled identifying the real namespace:
// g++ 4.0 in macosx:
00002dbe T __ZN7hideout9function1Ei // namespace hideout, function1 takes int, returns int
00002db0 T _function1
If user code will include both your header and otherlib.h then it will have to qualify which function it wants to call.
If you're really desperate, you could write a wrapper library that uses namespaces or prefixes or allows for the dlsym trick. This wrapper library would need to be dynamically linked (to avoid symbol conflicts). The dynamic library could then safely have the old static library embedded in it. Just make sure you don't export the symbols from the static library when making the dynamic wrapper library.
You can't resolve this at link time, so you'll need to resolve it at runtime via dynamic libraries. The symbol for those functions is essentially baked it once the library has been generated. If two libraries export the same symbol, they cannot both be linked with statically.