Sisay Zinabu
Sisay Zinabu

Reputation: 71

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

Upvotes: 0

Views: 258

Answers (3)

ade
ade

Reputation: 399

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");
}

Upvotes: 0

Paul R
Paul R

Reputation: 212949

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

Upvotes: 1

paxdiablo
paxdiablo

Reputation: 881293

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.

Upvotes: 1

Related Questions