Compilation issue in calling function of .o file in .cpp - c++

I have a temp1.c file having a function
int add(int a, int b){ return (a+b); }
and temp1.h file
int add(int,int)
I have created .o file from it by compiling
g++ -o temp1.o -c temp1.cpp
Now I have to use add function in temp2.cpp placed in a different directory. I have done
#include "temp1.h"
int main(){
int x = add(5,2);
}
I have to compile temp2.cpp with temp1.o so that I can create a temp2.exe which can call function add. How to compile it?

g++ temp2.cpp temp1.o -o temp2.exe

Like this:
temp2: temp1.o temp2.o
g++ temp1.o temp2.o -o temp
temp1.o: temp1.cpp
g++ -c temp1.cpp -o temp1.o
temp2.o: temp2.cpp
g++ -c your/path/to/temp2.cpp -o temp2.o

Related

calling c++ function from c

I need to access a C++ function from C but I get some error like :-
/tmp/ccUqcSZT.o: In function `main':
main.c:(.text+0x5): undefined reference to `load_alert_to_db'
collect2: error: ld returned 1 exit status
My main.c code is:-
#include <stdio.h>
extern void load_alert_to_db(void);
int main(void){
/* Create empty queue */
load_alert_to_db();
return 0;
}
C++ code implementation db_manager.cpp is:-
#include <sstream>
#include <iostream>
#include <sstream>
#include <string>
#include <ctime>
#include <cstdlib>
#include <algorithm>
#include <time.h>
#include <cstring>
#include <fstream>
//using namespace oracle::occi;
#include <iostream>
using namespace std;
extern "C" void load_alert_to_db(void)
{
cout<<"db occi"<<endl;
}
makefile is:-
CC= g++
all:
$(CC) -c -Wall -Werror -fPIC db_manager.cpp
$(CC) -shared -o libdb_manager.so db_manager.o
gcc -L/home/oracle/Desktop/storage/ -Wall main.c -o data -ldb_manager
gcc -o data main.c
clean:
rm -f *.o data
so please help me which one is my problem. I am also include
export LD_LIBRARY_PATH=/home/oracle/Desktop/storage/:$LD_LIBRARY_PATH
environmental variable in .bash_profile
gcc -o data main.c
Not sure why you have this line in your makefile since it will compile main.c without reference to the previously created library and hence cause an undefined-symbol error such as the one you're seeing.
This is especially so, since you appear to have done it the right way on the preceding line:
gcc -L/home/oracle/Desktop/storage/ -Wall main.c -o data -ldb_manager
However, the entire point of using makefiles is so that it figures out the minimum necessary commands for you, based on dependencies. Lumping a large swathe of commands into a single rule tends to defeat that purpose. You would be better off making your rules a little more targeted, such as (untested but should be close):
all: data
data: main.o libdb_manager.so
gcc -o data main.o -ldb_manager
main.o: main.c
gcc -o main.o main.c
libdb_manager.so: db_manager.cpp
g++ -c -Wall -Werror -fPIC -o db_manager.o db_manager.cpp
g++ -shared -o libdb_manager.so db_manager.o
That way, if you make a small change to one part (like main.c), it doesn't have to go and compile/link everything in your build tree.
Your makefile seems to be completely broken and random, and you're not even linking the required object files. You can simplify this:
all:
$(CC) -c -Wall -Werror -fPIC db_manager.cpp
$(CC) -shared -o libdb_manager.so db_manager.o
gcc -L/home/oracle/Desktop/storage/ -Wall main.c -o data -ldb_manager
gcc -o data main.c
to just this:
all:
gcc -Wall -c main.c
g++ -Wall -c db_manager.cpp
g++ main.o db_manager.o -o data
this is what I needed to do:
Supposing the C++ function is called Debug::Write(str)
Then in your hpp file do the following:
#ifdef __cplusplus
extern "C" void DebugTmp(char *str);
#endif
Then in the corresponding cpp file do this:
void DebugTmp(char *str)
{
Debug::Write(str);
}
Then in your C file where you call DebugTmp define the prototype:
void DebugTmp(char *str);
then call it as below:
static void MyFunction( void )
{
DebugTmp("This is debug trace\n");
}

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?

What is a fix for a constructor definition error?

So I have a class:
#include "Cool.h"
#include <iostream>
Cool::Cool()
{
//ctor
}
int getVar()
{
int pop = 22;
return pop;
}
and a header file:
#ifndef COOL_H
#define COOL_H
class Cool
{
public:
Cool();
int getVar();
};
#endif
But when I compile, I get an error that says
error: definition of implicitly-declared 'Cool::Cool()'
EDIT:
Don't know if it will help, but I also have a makefile:
program: main.o cool.o
g++ -o program main.o cool.o
cool.o: Cool.cpp Cool.h
g++ -c -o cool.o Cool.cpp
main.o: main.cpp cool.o
g++ main.cpp
EDIT 2: Full Error Message:
Cool.cpp:4:12: error: definition of implicitly-declared ‘Cool::Cool()’
Cool::Cool()
^
This:
cool.o: Cool.cpp Cool.h
g++ Cool.cpp
should be:
cool.o: Cool.cpp Cool.h
g++ -c -o cool.o Cool.cpp
For main.o::
main.o: main.cpp Cool.h
g++ -c -o main.o main.cpp
It is very confusing that you have the same file as both uppercase and lowercase. Does the problem persist after you rename everything to lowercase?
Solved it! I added this to the makefile:
Under main.o:
g++ -c -o main.o main.cpp

using global new and delete with dynamic lib

I am trying to overload global new and delete. So I have created a separate lib to keep both however when I try to use them i am seeing that my mehotds do not get called. Someone could tell me why and how I could fix, please?
Here is my code:
file my_operator.cpp
#include <cstdlib>
#include <cstdio>
void* operator new(size_t size)
{
puts("constructing");
void* p = malloc(size);
return p;
}
void operator delete(void *p) throw()
{
puts("deleting");
free(p);
}
file myclass.h
class clase
{
private:
int x;
public:
clase(int i):x(i){}
inline int getX(){return x;}
};
main.cpp
#include "myclass.h"
int main()
{
int k = 5;
int ret = 0;
clase* c = new clase(k);
delete c;
return ret;
}
what I have tried so far:
running this:
g++ -c my_operator.cpp -o my_operator.o && g++ main.cpp my_operator.o -o main
then launching ./main --> it works, my operators get called
however
running this:
g++ -c my_operator.cpp -o my_operator.o
ld -o my_operator.so my_operator.o -shared to create the .lib file
and then
g++ main
and finally running ./a.out does not work properly, my operators do not get called
Any clue?
Thanks in advance!
Your commands don't link your main with my_operator.so. You need something like the following:
g++ -Wall -Wextra -c -fPIC -o my_operator.o my_operator.cpp
g++ -shared -o libmy_operator.so my_operator.o
g++ -Wall -Wextra -c -o main.o main.cpp
g++ -o main main.o -lmy_operator
./main
Your main.cpp does not know that you overloaded the operators.
Put your overload operators in the header file.
Usefull links on this matter:
http://en.cppreference.com/w/cpp/memory/new/operator_new
http://www.cprogramming.com/tutorial/operator_new.html

Static Libraries which depend on other static libraries

I have a question about making static libraries that use other static libraries.
I set up an example with 3 files - main.cpp, slib1.cpp and slib2.cpp. slib1.cpp and slib2.cpp are both compiled as individual static libraries (e.g. I end up with slib1.a and slib2.a) main.cpp is compiled into a standard ELF executable linked against both libraries.
There also exists a header file named main.h which prototypes the functions in slib1 and slib2.
main.cpp calls a function called lib2func() from slib2. This function in turn calls lib1func() from slib1.
If I compile the code as is, g++ will return with a linker error stating that it could not find lib1func() in slib1. However, if I make a call to lib1func() BEFORE any calls to any functions in slib2, the code compiles and works correctly.
My question is simply as follows: is it possible to create a static library that depends on another static library? It would seem like a very severe limitation if this were not possible.
The source code for this problem is attached below:
main.h:
#ifndef MAIN_H
#define MAIN_H
int lib1func();
int lib2func();
#endif
slib1.cpp:
#include "main.h"
int lib1func() {
return 1;
}
slib2.cpp:
#include "main.h"
int lib2func() {
return lib1func();
}
main.cpp:
#include <iostream>
#include "main.h"
int main(int argc, char **argv) {
//lib1func(); // Uncomment and compile will succeed. WHY??
cout << "Ans: " << lib2func() << endl;
return 0;
}
gcc output (with line commented out):
g++ -o src/slib1.o -c src/slib1.cpp
ar rc libslib1.a src/slib1.o
ranlib libslib1.a
g++ -o src/slib2.o -c src/slib2.cpp
ar rc libslib2.a src/slib2.o
ranlib libslib2.a
g++ -o src/main.o -c src/main.cpp
g++ -o main src/main.o -L. -lslib1 -lslib2
./libslib2.a(slib2.o): In function `lib2func()':
slib2.cpp:(.text+0x5): undefined reference to `lib1func()'
collect2: ld returned 1 exit status
gcc output (with line uncommented)
g++ -o src/slib1.o -c src/slib1.cpp
ar rc libslib1.a src/slib1.o
ranlib libslib1.a
g++ -o src/slib2.o -c src/slib2.cpp
ar rc libslib2.a src/slib2.o
ranlib libslib2.a
g++ -o src/main.o -c src/main.cpp
g++ -o main src/main.o -L. -lslib1 -lslib2
$ ./main
Ans: 1
Please, try g++ -o main src/main.o -L. -Wl,--start-group -lslib1 -lslib2 -Wl,--end-group.
Group defined with --start-group, --end-group helps to resolve circular dependencies between libraries.
See also: GCC: what are the --start-group and --end-group command line options?
The order make the difference. Here's from gcc(1) manual page:
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.