Function Not Found in Custom Library - c++

I have a custom-defined library (and corresponding cpp file) included by a test file. When I try to call the function in the test file, it gives me the error, "Undefined reference to < function name>." I'm not very experienced with putting stuff in library files, so any help is appreciated.
input.h
#ifndef LOC_H
#define LOC_H
#include<vector>
struct loc{
int room, row, col;
char c;
bool stacked;
//loc *north, *east, *south, *west;
};
#endif
void Input(std::vector<std::vector<std::vector<loc> > > &b, loc & start);
input.cpp
#include<iostream>
#include<cstdlib>
#include<unistd.h>
#include<getopt.h>
#include "input.h"
using namespace std;
void Input(vector<vector<vector<loc> > > &b, loc & start) {
//Do stuff
}
test.cpp
#include<iostream>
#include "input.h"
#include<vector>
using namespace std;
int main(int argc, char* argv[]) {
vector<vector<vector<loc> > > building;
loc start = {0, 0, 0, '.', false};
Input(building, start);
}

There is not library involved at all. You just need to link the object files of all source files when you are linking. The easiest way is to compile it from source:
g++ -o test test.cpp input.cpp
When you have a larger project you might want to compile separately, controlled by a makefile or script.
g++ -c test.cpp
g++ -c input.cpp
g++ -o test test.o input.o
This looks a bit clumsy, but shows what is done behind the scenes.

Related

Problems with Makefile and compiling a cpp file marks error in a function declared in other file

I have problems with my Makefile.
I used the following structure to generate the .o files of each cpp file, but does not work (using c works without problems, I cant find what is the problem)
%.o : %.cpp %.h
g++ -c -Wall $< -o $#
And the error while compiling is a function is declared in a separated h and cpp file and added to the main file. But when I try to generate de .o file of main.cpp marks error in the function.
The command I used to compile the main.cpp -> g++ -c main.cpp -o main.o
The error that gives me is:
main.cpp: In function ‘int main(int, char)’:
main.cpp:9:9: error: ‘number’ was not declared in this scope9 | number();
This is the compiler that I used for it:
g++ (Ubuntu 11.2.0-19ubuntu1) 11.2.0
Linux 5.15.0-40-generic
Please, anyone could explain me if I'm doing wrong of something is left
/*main.cpp*/
#include <iostream>
#include "numb.h"
using namespace std;
int main(int argc, char* argv[])
{
cout<<"Run"<<endl;
number();
cout<<"end Run"<<endl;
return 0;
}
/*end main.cpp*/
/*numb.cpp*/
#include <iostream>
#include "numb.h"
using namespace std;
int number()
{
cout<<"Function"<<endl;
return 117;
}
/*end numb.cpp*/
/*numb.h*/
#include <iostream>
#define NUMB_H
#ifndef NUMB_H
int number();
#endif
/*end numb.h*/
You got the header guard in the wrong order.
Instead of:
#define NUMB_H
#ifndef NUMB_H
It is supposed to be:
#ifndef NUMB_H
#define NUMB_H
When compiling specify both CPP files, because #include fixes compile errors, but does not fix linker errors
g++ -c main.cpp numb.cpp ...
As a rule, in header files nothing have to be outside the #define guards:
/*numb.h*/
#define NUMB_H
#ifndef NUMB_H
#include <iostream>

C++ Undefined Reference When Compiling .h and .cpp in Subfolders

Long story short I want to put my .h and .cpp files in subfolders (include and src respectively) and reference them in my main.cpp file but I am receiving an error of:
main.cpp:(.text+0x47): undefined reference to `Kmer::Kmer()'.
when compiling using:
g++ -I /path/to/MyFolder/include main.cpp.
My files are structured like below:
MyFolder
main.cpp
include
Kmer.h
src
Kmer.cpp
//main.cpp
#include <iostream>
#include "Kmer.h"
using namespace std;
int main() {
Kmer k;
return 0;
};
//Kmer.h
#pragma once
class Kmer{
public:
Kmer();
protected:
private:
};
//Kmer.cpp
#include "Kmer.h"
#include <iostream>
using namespace std;
Kmer::Kmer(){
// code here
cout << "Kmer created" << endl;
}
I appreciate the help!
You are not compiling Khmer.cpp. You need to add it to your g++ compile line
g++ -o <YOUR APPLICATION NAME> -I /path/to/MyFolder/include main.cpp src/Khmer.cpp

C++ linker error despite using g++, clang etc to compile

I'll start by showing you the error I have been getting:
Henrys-MacBook-Pro-2:assignment1 HenryDashwood$ clang++ main.cpp
Undefined symbols for architecture x86_64:
"clear()", referenced from:
_main in main-a61991.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I've been trying to move some functions into a source.cpp file with prototypes in a header.h file. The code works fine when I have it all in the main.cpp file. It also works when I move the function prototype to a header file. However, when I then also move the functions to the source file, it errors me! Here are the relevant bits of my code:
main.cpp
#include <string>
#include <iostream>
using namespace std;
#include "header.h"
int main()
{
char quit, choice;
int term, day, hour;
string termName, dayName;
clear();
return 0;
}
header.h
#define TERMS 4
#define DAYS 7
#define HOURS 8
struct TTcell
{
string subject;
string lecturer;
string roomName;
};
struct TTcell timetables[8][7][4];
void clear();
source.cpp
#include <string>
#include <iostream>
using namespace std;
#include "header.h"
void clear()
{
for (size_t i = 0; i < TERMS; i++) {
for (size_t j = 1; j <= DAYS; j++) {
for (size_t k = 1; k <= HOURS; k++) {
timetables[k][j][i].subject = "";
timetables[k][j][i].lecturer = "";
timetables[k][j][i].roomName = "";
}
}
}
}
This is an example using one function to keep the question readable. They all seem to have the same affliction. I saw on other posts people got similar errors because of the compiler they were using. I've tried c++, g++ and clang++, all to no avail.
Thank you in advance for any ideas you come up with!
You have two options to make this compile.
Compile all the cpp files on one line
g++ main.cpp source.cpp -o main
Compile separately and link
g++ -c main.cpp
g++ -c source.cpp
g++ -o main main.o source.o
This is a bog-standard failure to bring in your source files, and has nothing to do with your compiler.
Henrys-MacBook-Pro-2:assignment1 HenryDashwood$ clang++ main.cpp
You didn't build & link source.cpp.
So, as far as Clang knows, the definition for clear() indeed does not exist.
Henrys-MacBook-Pro-2:assignment1 HenryDashwood$ clang++ main.cpp source.cpp

Dynamic library using static library in c++ name mangling error

I am trying to create a dynamic(.so) wrapper library along mongoDB c++ driver. There is no problem with the compilation but when I test it in a C++ sample program i get the error
undefined symbol: _ZN5mongo18DBClientConnection15_numConne
which i assume has something to do with name mangling issues.
I compiled the library as
g++ -fPIC -shared mongoquery.cpp -I/pathto/mongodriver -lmongoclient -lboost_thread-mt -lboost_filesystem -lboost_program_options -o libmongoquery.so
Here's the program I am using for testing:
#include <iostream>
#include <dlfcn.h>
#include "mongoquery.hpp"
using namespace std;
int main()
{
void *lib_handle;
int (*fn)(int *,string);
lib_handle=dlopen("./libmongoquery.so",RTLD_NOW);
if(!lib_handle)
{
cerr<<"Error"<<dlerror();
return 1;
}
fn=(int (*)(int *,string))dlsym(lib_handle,"count_query");
string q="{}";
int n;
(*fn)(&n,q);
cout<<n;
dlclose(lib_handle);
return 0;
}
the header mongoquery.hpp contains
#include <iostream>
#include <client/dbclient.h>
#define HOST "localhost"
#define COLLECTION "test.rules"
using namespace mongo;
using namespace std;
class mongoquery
{
private:
string q;
mongo::DBClientConnection c;
public:
mongoquery(string);
int result_count();
};
int count_query(int *,string);
Thanks
The answer can be followed from this question
Dynamic library uses statics libraries, undefined symbols appears
Added for achival purpose

C++ compiling problem; class methods

I have started writing a very simple class, and all kinds of class methods seem to give me problems. I hope the problem is me and the solution is simple.
The command g++ -o main main.cpp gives the folowing output:
/usr/bin/ld: Undefined symbols:
Lexer::ConsoleWriteTokens()
collect2: ld returned 1 exit status
main.cpp:
#include<iostream>
#include"lexer.h"
int main(){
Lexer lexhnd = Lexer();
std::cout << "RAWR\n";
lexhnd.ConsoleWriteTokens();
std::cout << "\n\n";
return 0;
}
lexer.h:
#ifndef __SCRIPTLEXER
#define __SCRIPTLEXER
#include <iostream>
#include <string>
#include <vector>
#define DEF_TOKEN_KEYWORD 0
struct token{
int flag;
std::string data;
};
class Lexer
{
public:
// bool IsTrue();
// bool AddLine(char * line);
void ConsoleWriteTokens(void);
private:
std::vector<token> TOK_list;
};
#endif
lexer.cpp:
bool Lexer::IsTrue(){
return true;
};
bool Lexer::AddLine(char * line){
token cool;
cool.data = line;
TOK_list.push_back(cool);
string = line;
return true;
};
void Lexer::ConsoleWriteTokens(void){
for (int i = 0; i < TOK_list.size(); i++){
std::cout << "TOKEN! " << i;
}
return 0;
};
I am using g++ in xcode btw.
Thankyou very much in advance, I have been on this problem for a few hours.
EDIT:
g++ -o main lexer.h main.cpp
or
g++ -o main lexer.cpp main.cpp
or
g++ -o main main.cpp lexer.cpp
do NOT work either.
-Hyperzap
Your not compiling the lexer.cpp code.
Try
g++ -o main main.cpp lexer.cpp
as your compilation command.
PROBLEMS IN THE lexer.cpp
You probably want to include the lexer header in the lexer.cpp file
#include "lexer.h"
Also, you don't want to return an integer from void functions.
void Lexer::ConsoleWriteTokens(void){
for (int i = 0; i < TOK_list.size(); i++){
std::cout << "TOKEN! " << i;
}
//This function is void - it shouldn't return something
//return 0;
};
Finally, you have some problems withs this function
bool Lexer::AddLine(char * line){
token cool;
cool.data = line;
TOK_list.push_back(cool);
//what is this next line trying to achieve?
//string = line;
return true;
};
I'm not sure what you are trying to achieve with the line I commented out,
it doesn't seem to do anything and string isn't defined (did you mean std::string mystring = line;)
Finally, don't forget to uncomment the functions declaired in lexer.h that you are defining in lexer.cpp.
Include all the .cpp files in the command line, like this:
g++ -o main main.cpp lexer.cpp
When your project grows, it becomes wise to manage your project in some automatic way: Makefiles, ant, or some IDE-integrated project file.
Well g++ -o main main.cpp lexer.cpp sould do the trick. However I suggest making makefile files. When having a multiple amount of file they come in handy.
I would also suggest adding some optimization to your compilation like -O3 or -O2 (O is a letter o not zero digit!). The difference in execution speed is very noticable. Also if you are goig to make libraries out of your files, why not using --shared option that will create a liked library. I find making shared libraries very useful.