C++ function not declared after DLL linkage with g++ at CentOS7 - c++

I am trying to link a dll with a very simple testing program, but I am getting an error, that I will describe at the end of the post.
frvt11.h - Interface (just relevant code) I need to implement to create my dll
namespace FRVT {
class Interface {
public:
static std::shared_ptr<Interface>
getImplementation();
}
}
implementation.h - Header of my implementation of Inteface
#include "frvt11.h"
namespace FRVT {
class Implementation : public FRVT::Interface {
public:
static std::shared_ptr<Interface>
getImplementation();
}
}
implementation.cpp - My implementation of Interface
UPDATE: change from Implementation::getImplementation to Interface::getImplementation
#include "implementation.h"
using namespace FRVT;
std::shared_ptr<Interface>
Interface::getImplementation() {
std::cout<<"getImplementation";
return std::make_shared<Implementation>();
}
main.cpp
UPDATE: Explicitly indicate the namespace Interface::
#include "frvt11.h"
using namespace FRVT;
int main(){
auto obj = Interface::getImplementation();
return 0;
}
compilation directives
UPDATE: include of -L/dll-directory where are all .h, .cpp and dll
g++ -std=c++11 -c -Wall -Werror -m64 -fPIC implementation.cpp
g++ -std=c++11 -shared -m64 -o libimplementation.so implementation.cpp
g++ -std=c++11 -Wall -m64 -o main main.cpp -L/dll-directory -limplementation
error
UPDATE: Original problem solved
main.cpp: In function 'int main()':
main.cpp:6:34: error: 'getImplementation' was not declared in this scope
auto obj = getImplementation();
How to solve this error? I was expecting that the linker would do the "magic" to say to main.cpp, that the implementation of referred function would be at the dll. What am I doing wrong?

At implementation.cpp I've changed from:
Implementation::getImplementation()
to:
Interface::getImplementation()
At main.cpp I've explicitly indicate the interface, like bellow:
auto obj = Interface::getImplementation();
And finally I've used the -L directive to indicate where was the the generated dll.

Related

Force alle functions in shared library to be defined

I want to write a shared library and I want to get a compiler/linker error if I forgot to implement some functions.
Consider the following case:
test.h
class Test {
public:
Test();
};
test.cpp
#include "test.h"
main.cpp
#include "test.h"
int main() {
new Test();
}
If I create a library with this command gcc -c -fpic test.cpp && g++ -shared -o libtest.so -Wl,--no-undefined -Wl,--no-allow-shlib-undefined test.o there is no error message, but the library is broken. Is there a way to force the creation of a not broken library?
Edit: adding additional flag, but doesn't change result
These codes have been modified:
test.h :
class Test {
public:
Test();
};
test.cpp :
#include "test.h"
Test::Test(){} // you must implement the constructor
You must have to implement the constructor, and if not, you get an error "undefined reference to `Test::Test()'".
main.cpp :
#include <iostream>
#include "test.h"
using namespace std;
int main(void)
{
Test* t = new Test(); // you must define a pointer
cout << "test* was created: " << t << endl;
delete t;
t = nullptr;
return 0;
}
Now all the code is OK. Then we create a shared-library with the following command:
g++ -shared -o test.so -fPIC test.cpp
Finally, we compile the main.cpp file at the same time as referring to the test.so shared-library and get the exe output, by the command below:
g++ -g main.cpp test.so -o test.exe

C++ objcopy to make class method weak

I have this header file:
weather.h
#ifndef _WEATHER_H_
#define _WEATHER_H_
#include <string>
using namespace std;
class Weather {
private:
int temp;
public:
Weather();
string announce();
};
#endif
When I compile the related source file, I want to make announce and Weather (the default constructor) weak during compile time.
To do so, the flow looks something like:
g++ -std=c++11 -g -Wall -c weather.cpp
objcopy --weaken-symbol=announce --weaken-symbol=Weather weather.o weather.o
However, when I then compile another version of weather without the weakening? I still get a duplicate symbol error.
I know --weaken exists, but this is just a sample and I do not want to blanket weaken every method in the class.
Weakening the symbols in the one file and linking all the objects together works for me. Make sure you are relinking all the objects (including all constructors).
weather1.cpp
Weather::Weather() {}
string Weather::announce()
{
return string("Bad weather");
}
weather2.cpp
Weather::Weather() {}
string Weather::announce()
{
return string("Bad weather 2");
}
build.sh
g++ weather1.cpp -c -o weather1.o
g++ weather2.cpp -c -o weather2.o
g++ test.cpp -c -o test.o
objcopy --weaken-symbol=_ZN7Weather8announceEv --weaken-symbol=_ZN7WeatherC2Ev --weaken-symbol=_ZN7WeatherC1Ev weather2.o weather2.o
g++ *.o -o test.out
Depending on whether I weaken weather1.o or weather2.o, I see different outputs from my test main function:
int main()
{
Weather w;
std::cout << w.announce() << "\n";
return 0;
}

C++ gcc Namespace not found

I know there are many similar topics but there are equally many unique mistakes that may lead to this problem (so I think). Therefore I ask, after some research.
My problem is that the compiler, GNU GCC, when compiling one file does not see my namespace declared in another file. The IDE (CodeBlocks) evidently does see it as it auto-completes the name of the namespace. I tried to isolate the problem and came up with this:
File main.cpp:
namespace MyName
{
int MyVar;
}
#include "T1.cpp"
int main()
{
return 0;
}
File T1.cpp:
using namespace MyName;
error: 'MyName' is not a name-space name.
In my project I have a header file, say T1.h, and an implementation file T1.cpp — and MyName isn't accessible in either of them.
Any help or guidance would be appreciated.
What's happening is that CodeBlocks is compiling both main.cpp and T1.cpp. Here is what happens when you try to compile each one:
main.cpp:
$ g++ main.cpp
$
T1.cpp
$ g++ T1.cpp
T1.cpp:1:17: error: ‘MyName’ is not a namespace-name
using namespace MyName;
^
T1.cpp:1:23: error: expected namespace-name before ‘;’ token
using namespace MyName;
^
$
T1.cpp, when compiled on it's own, has no knowledge of MyName. To fix this, don't include .cpp files, and put your declarations in header files.
Edit: From what I gather, this may be a better way to organize your example:
T1.h:
namespace MyName {
extern int MyVar;
}
T1.cpp
#include "T1.h"
int MyName::MyVar = 5;
main.cpp
#include "T1.h"
#include <iostream>
using namespace MyName;
int main()
{
std::cout << MyVar << std::endl;
return 0;
}
Now it will compile correctly:
$ g++ -c T1.cpp -o T1.o
$ g++ -c main.cpp -o main.o
$ g++ T1.o main.o
$ ./a.out
5

C++ shared library undefined reference

i'm having something like these files:
libfoo.h
class foo
{
public:
foo() = default;
virtual ~foo();
};
libfoo.cpp
#include "libfoo.h"
foo::~foo() { /* code here */ }
test.cpp
#include <libfoo.h>
int main()
{
foo f;
}
i compile libfoo.h and libfoo.cpp into a shared library and all that is fine.
but when i then try to use the library in test.cpp i get undefined reference to the destructor ~foo().
this error however does not occur if i define the destructor directly in libfoo.h. i have this problem with all functions defined outside the class in my library so im guessing it has something to do with the compilation process (it compiles fine however)
i compile the library like this:
g++ -std=c++0x -Wall -Werror -fPIC -c -o libfoo.o libfoo.cpp
g++ -shared libfoo.o -o libfoo.so
any ideas as to what i might be doing wrong?
(all the functions that i declare inclass, like template functions works fine and causes no undefined reference)
I tried to reproduce the error, but I failed.
I created the files (with slight modifications):
// libfoo.h
struct foo { virtual ~foo(); };
// libfoo.cpp
#include "libfoo.h"
foo::~foo() {}
// test.cpp
#include "libfoo.h"
int main() { foo f; }
Built like this:
$ g++ -std=c++0x -Wall -Werror -fPIC -c -o libfoo.o libfoo.cpp
$ g++ -shared libfoo.o -o libfoo.so
$ g++ test.cpp -L. -lfoo
And ran like this:
$ env LD_LIBRARY_PATH=. ./a.out
I got no errors. Are you sure there is a problem with your code?

C++ classes in separate file [duplicate]

This question already has answers here:
creating classes link error
(2 answers)
Closed 8 years ago.
I'm trying to learn how to make classes in C++ where I use a header file, a .cpp file that contains the class function definitions, and a main .cpp file. Here is what I have (taken from an example)
in class.h
class MyClass
{
public:
void foo();
int bar;
};
in class.cpp
#include "class.h"
using namespace std;
void MyClass::foo()
{
cout<< "test";
}
in main.cpp
#include "class.h"
using namespace std;
int main()
{
MyClass a;
a.foo();
return 0;
}
Compiling the main.cpp results in this error:
[Linker error] C:\:(.text+0x16): undefined reference to `MyClass::foo()'
collect2: ld returned 1 exit status
Do I need to compile the class.cpp or class.h? Am I missing a way of linking class.h with class.cpp? If so how do I link them?
You need to compile the implementation files into object files and link them together. The following is an example for when you are using g++:
g++ -c class.cpp -o class.o
g++ -c main.cpp -o main.o
g++ class.o main.o -o main
./main
In reality, you would add more options like -std=c++11 -O3 -Wall -Wextra -Werror etc.
You can try this on Linux shell using g++
Compile Create object files of main.cpp and class.cpp called main.o and class.o
g++ -c class.cpp
g++ -c main.cpp
Linking the object codes main.o and class.o to create executable file called program
g++ -o program main.o class.o
then run the program executable file
./program
You are likely to be compiling only main.cpp and not class.cpp.
What command are you using to generate the output ?
This should work fine :
g++ class.cpp main.cpp -o class
Its working fine
I tried the code in my Compiler
MyClass.h
#include <iostream>
class MyClass
{
public:
void foo();
int bar;
};
MyClass.cpp
#include "MyClass.h"
using namespace std;
void MyClass::foo()
{
cout<< "test";
}
Main.cpp
#include <iostream>
#include "MyClass.h"
int main(int argc, const char * argv[])
{
MyClass a;
a.foo();
return 0;
}
Ive tried the code in Xcode.
Its working just fine.
Use compiler option -I<dir of .h file> while compiling .cpp file. Compile both the .cpp files