C++ clang compiling & linking on ipad, Linker issue - c++

please may you advise how I may compile & run main.cpp while compiling and linking the my_class.cpp & my_class.h class files,please note that this is running on an iPad using the “Code” app by “thebaselab”, which has offline clang++ 13.0. developer says its possible to work using the below method, however theres no output.
I compile seperately:
clang++ main.cpp -c
clang++ my_class.cpp - c
It seems to produce the main.o and my_class.o files so I may run using:
clang++ main.o my_class.o
This doesnt seem to run as no output, please may you advise if you can see the problem in my code or in compiling.?
I believe there is an issue with linking these files together, as when I have the class defined in main there’s no issues.
My code base:
main.cpp
// Created on iPad.
#include <iostream>
#include <vector>
#include "my_class.h"
using namespace std;
int main() {
cout << "Hey\n";
my_class obj1 = my_class("test");
obj1.display();
cout << "Hello World!";
return 0;
}
my_class.h
#ifndef _my_class_H_
#define _my_class_H_
class my_class
{
private:
std::string name = "";
public:
my_class(std::string name_tmp); // No-args constructor // Copy constructor
~my_class(); // Destructor
void display();
};
#endif
my_class.cpp
#include <iostream>
#include "my_class.h"
// 1-args constructor
my_class::my_class(std::string name_tmp){
name = name_tmp;
}
// Destructor
my_class::~my_class() {
std::cout << "Destructing\n";
}
void my_class::display(){
std::cout << name << "\n";
}

Thanks to #Quimby,
I ran clang++ -o a.out main.o my_class.o then just a.out and it works on my iPad.

Related

In c++ , shared library function with __attribute__ ((constructor)) not getting invoked during loading of the library

I am trying to created a shared library in c++ and to initialize the library i define a function with __attribute__ ((constructor)) , but this function is not at all getting invoked.
Any idea why __attribute__ ((constructor)) is not getting called here?
lib.h file
#include <iostream>
using namespace std;
class lib {
public:
int i=0;
lib() { i=5; }
~lib() { cout << "calling lib destructor" << endl; }
static lib* getInstance();
void set() { i=i+25; }
int get() { return i; }
private:
static lib Obj;
};
lib.cpp
#include "lib.h"
lib lib::Obj;
lib* lib::getInstance()
{
return &Obj;
}
void __attribute__ ((constructor)) init_fn(void) ;
void init_fn(void)
{
lib::getInstance()->set();
}
i am creating a shared object using below command
g++ -Wall -Wextra -fPIC -shared lib.cpp -Wl,-soname,libfoo.so -o libfoo.so
Once shared library is created , i am linking it with a main program
main.cpp
#include <iostream>
#include "lib.h"
using namespace std;
int main()
{
cout << lib::getInstance()->get() << endl; // Expecting a output of 30, but always getting 5
cout << "End of program" << endl;
return 0;
}
g++ -L./ -Wall -o main main.cpp -lfoo (linking with shared object libfoo.so)
output:
./main
5
End of program
calling lib destructor
init_fn() function with constructor attribute is not at all getting invoked during loading of the shared object libfoo.so.
Tried on various c++ compilers (clang and g++), but i am not able to make it work.
Anything i am doing wrong while creating shared object? Please help me .

C++ Constructor not showing output

I have the following 3 files, main.cpp and then a class defintion including a header file for the class:
main.cpp:
#include <iostream>
#include "data_vars_class.hpp"
int main () {
DataVars dataVars();
return 0;
}
data_vars_class.hpp:
#include <string>
#include <vector>
class DataVars
{
private:
std::vector<std::string> csv_card_names;
public:
DataVars();
void getCSVData();
};
data_vars_class.cpp:
#include <iostream>
#include <vector>
#include <string>
#include "data_vars_class.hpp"
DataVars::DataVars()
{
std::cout << "constructor?";
getCSVData();
}
void DataVars::getCSVData()
{
std::cout << "Getting csv data!";
}
The problem is when I build and execute the code, I just get an empty terminal. I know that both data_vars_class.hpp and data_vars_class.cpp are being included with the build, this is my build command in Geany:
g++ main.cpp data_vars_class.cpp -o a.out
How come i'm not seeing the cout output in the terminal, like in the constructor shouldnt i see "constructor?" in the terminal?
Thanks
by building the binary file gets created to run the code you have to write ./a.out in the terminal after building it.
g++ main.cpp data_vars_class.cpp -o a.out
./a.out

Simple multifile c++11 compilation g++ when defining personal namespace in classes

Working with a Fedora g++, I've noticed something anoying for me.
I think I misundertands g++ behaviors with namesapce and header files.
You will see 2 versions of a very simple Class and a main function.
First one is fully embeded in single file named "mainfull.cpp" and compiles silently.
Second one is the same code distributed in three files "MaClass.hpp", "MaClass.cpp" and "main.cpp". The issue come from this version.
$ g++ -o doit MaClass.cpp main.cpp
/usr/bin/ld : /tmp/cc9IOJE8.o : in function « main » :
main.cpp:(.text+0x10) : undefined reference to « test::example::MaClass::doit() »
collect2: error: ld returned exit status 1
But the error vanishes with namespace suppression or when changing the include from the header file to the implementation file.
Here are my questions :
What is the good way to include multifiles classes with namespaces ?
How should one uses g++ in that case ?
But I am a chatterbox ; here is the code :
mainfull.cpp : no pb when compiling with : g++ -o mainfull mainfull.cpp
#include <iostream>
namespace test {
namespace example {
class MaClass {
public:
void doit();
};
}
}
int main() {
test::example::MaClass c;
c.doit();
return 0;
}
namespace test {
namespace example {
void MaClass::doit() {
::std::cout << "I did it !" << ::std::endl;
}
}
}
And here the version on witch I get doubts: (the whole remaining files)
MaClass.hpp
#ifndef MACLASS
#define MACLASS
#include <iostream>
namespace test {
namespace example {
class MaClass {
public:
void doit();
};
}
}
#endif
MaClass.cpp
#include "MaClass.hpp"
namespace test {
namespace example {
void MaClass::doit() {
::std::cout << "I did it !" << ::std::endl;
}
}
}
main.cpp
#include "MaClass.hpp"
int main() {
test::example::MaClass c;
c.doit();
return 0;
}
The issue occurs with :
g++ -o doit MaClass.cpp main.cpp -std=c++11
I don't know the reason of that. I know that the problem come from me and not from Fedora.
Any help would be apreciated.
I have no problem on Visual Studio 2019 neither with the one nor the other version ; everything is automatic, I should have miss something.

Linking shared libraries with executables

I have a small doubt in the compilation of a c++ code along with a shared library.
So I have two files main.cpp and sample.cpp.
main.cpp
#include <iostream>
using namespace std;
#include "sample.h"
myStruct obj;
void populateData() {
obj.s = "hello world";
}
myStruct giveData() {
cout << "Inside main: " << obj.s << endl;
return obj;
}
int main() {
populateData();
}
sample.h
#ifndef SAMPLE_H
#define SAMPLE_H
#include <string>
struct myStruct {
std::string s;
void populateData();
};
myStruct giveData();
#endif
sample.cpp
#include "sample.h"
#include <iostream>
#include <boost/python.hpp>
using namespace std;
void myStruct :: populateData() {
cout << giveData().s;
}
BOOST_PYTHON_MODULE(boosts) {
using namespace boost::python;
class_<myStruct>("struct")
.add_property("s", &myStruct::s)
.def("populateData", &myStruct::populateData)
;
}
I compile the program using
g++ -c -fPIC sample.cpp
g++ -c -fPIC main.cpp
g++ -shared -Wl,-soname,boosts.so -o boosts.so sample.o main.o -lpython2.7 -lboost_python
g++ -o main main.o
./main
Now, when I run the main, it populates the string inside the obj. But when I run a python script, that imports the boosts.so, the obj.s is empty.
I am guessing it is because the library boosts.so is not properly linked with the executable main.
How do I fix this?

Ttrying to understand Classes and headers

**PROBLEM SOLVED. It appears that i had created an extra header by mistake, and since i deleted him , it worked. **
So i am trying to understand about classes and headers and how i can make them work together.
I am following an online tutorial but it seems that something is going wrong in my code.
The problem is that when i try to run the main it gives me this error:
multiple definition of Cat::speak() and all the other functions.
main.cpp
#include <iostream>
#include "class.h"
using namespace std;
int main()
{
Cat jim;
jim.makehappy();
jim.speak();
Cat george;
george.makesad();
george.speak();
return 0;
}
class.cpp
#include <iostream>
#include "class.h"
using namespace std;
void Cat::speak()
{
if (happy)
{
cout << "meoww" << endl;
}
else
{
cout << "sssss" << endl;
}
}
void Cat::makehappy()
{
happy = true;
}
void Cat::makesad()
{
happy = false;
}
class.h
#ifndef CLASS_H_INCLUDED
#define CLASS_H_INCLUDED
class Cat
{
private:
bool happy;
public:
void makehappy();
void makesad();
void speak();
};
#endif // CLASS_H_INCLUDED
From what you have shown here there should be no problems. What you could do to temporarily resolve this to find out if you are actually defining this function in several places is to wrap your class in a namespace.
class.h
#ifndef CLASS_H_INCLUDED
#define CLASS_H_INCLUDED
namespace myNamespace {
class Cat {
private:
bool happy;
public:
void makehappy();
void makesad();
void speak();
};
} // namespace myNamespace
#endif // CLASS_H_INCLUDED
class.pp
#include <iostream>
#include "class.h"
// using namespace std; // Don't Use - This is Bad Practice
// Can cause name clashing when trying to resolve name lookup
namespace myNamespace {
void Cat::speak() {
if (happy) {
std::cout << "meoww" << std::endl;
} else {
std::cout << "sssss" << std::endl;
}
}
void Cat::makehappy() {
happy = true;
}
void Cat::makesad() {
happy = false;
}
} // namespace myNamespace
main.cpp
#include <iostream>
#include "class.h"
// using namespace std; // Again -Bad Practice
int main() {
using namespace myNamespace;
Cat jim;
jim.makehappy();
jim.speak();
Cat george;
george.makesad();
george.speak();
return 0;
}
Try this to see if you are getting the same compiler error. This should help you to see if you are defining this function in multiple spaces. Also by removing the using namespace std; and just using the scope resolution operator to the std:: namespace will help to eliminate any possible problems and any possible future problems.
How are you compiling the code? You need to make sure that you are building the specific "class.o" and "main.o" files separately before linking them together. Here is an example Makefile.
all: main
main: main.o class.o
g++ main.o class.o -o main
main.o: main.cpp class.h
g++ -c main.cpp
class.o: class.cpp class.h
g++ -c class.cpp
It looks like you are using double inclusion guards so I don't think that is the problem. Check out this answer for a more in-depth explanation of what is happening: Error with multiple definitions of function