views:

810

answers:

3

Hi,

I seem to be forgetting my C++ ...
I'm trying to declare some functions in C in separate sources, and including the appropriate .h when necessary. It compiles OK; but the problem is during linking, where the linker complains about functions already being defined.

I even tried defining the functions as extern, in a (vain) attempt to just declare the functions and let the implementation come true only on the .c.

This is an abridged description of my code:

common.h

#include <stdio.h>

module1.h

#include "common.h"
#ifndef MODULE1_H_
#define MODULE1_H_
int init(int option);
int open(char* db, char* username, char* password);
int get(int handler, int date[2], int time[2], int* data, int& rowsize, int& numrows);
int put(int handler, int* data, int& datasize, int& numrows);
int close(int handler);
int finalize();
#endif /* MODULE1_H_ */

module2.h

#include "common.h"
#ifndef MODULE2_H_
#define MODULE2_H_
int get1(int handler, int date, int time, int *data, int& datasize, int& rowsize);
int put1(int handler, int* data, int datasize);
#endif /*MODULE2_H_*/

module1.cpp

#include "module1.h"
int init(int option) { ... }
int finalize() { ... }
int get(int handler, int date[2], int time[2], int* data, int& rowsize, int& numrows) {
    ....
}
...

module2.cpp

#include "module1.h"
#include "module2.h"
int get1(int handler, int date, int time, int* data, int rowsize) {
  int daterange[2]={date,date};
  int timerange[2]={time,time};
  int rsize, numrows, result;
  result=get(handler, daterange,timerange, data, rsize, numrows);
  rowsize=rsize; 
  if(numrows!=1) printf("Uh oh...\n");
  return result;
}
...

Compilation & linkage:

g++ -o module1.o -c module1.cpp
g++ -o module2.o -c module2.cpp
g++ -fPIC -shared -o library.so module1.o module2.o

As I said, it compiles OK. The problem is during linkage, where the linker "sees" that there are two implemented functions from module1.h: one from the inclusion of module1.h in module1.cpp; and the other from the inclusion of module1.h together with module2.h in module2.cpp.

I know the functions are supposed to be declared, but I'm obviously doing a faux-pas. Could someone please point out where it is? Thank you in advance.

+4  A: 

Your function names need to be changed. There are already functions with some of those names you mentioned (Example: open) and they are probably being included by something you are linking to.

Brian R. Bondy
"open" is just an example; in my project it's called "ifxopen". When you say that "there are already functions ..." you mean they're "Standard" functions, or you mean it's a name collision in this particular project?
jbatista
what's the exact linking error?
Brian R. Bondy
Example:<br>src/ifx4cldb.o: In function `ifxcount_': <br>include/ifx2f.h:215: multiple definition of `ifxcount_' <br>src/ifx2f.o:include/ifx2f.h:215: first defined here
jbatista
I think I have to see the ifx2f.h file or the line 215 + the first few lines.
Brian R. Bondy
The problem may be a bad header guard. Example #ifdef MODULE1_H #define MODULE_H
Brian R. Bondy
+1  A: 

G'day,

Don't you need to tell the compiler and linker that this is C and not C++ by using the extern dec.?

extern "C" {
    #include "my_bits_of_C.h"
}

to let the linker know that there's no name mangling going on?

HTH

cheers,

Rob Wells
A: 

Thank you all for your replies and comments. I figured out the problem (it turned out to be a very stupid thing) and am close to solving it (hopefully).

It turns out it comes from another include file (cfortran.h) which implements a layer for using C function calls in Fortran (and vice-versa). It's very useful and I've been using it with success up until now, but I was "blinded" by the errors; that include's documentation states that care should be taken when using it in C++ context (not in C) but this is the first instance where that warning actually produces effects.

Thank you once more for your help.

jbatista
In other words: the problem comes from using cfortran.h ; if I leave it out, the compilation and linkage happens with no problem.
jbatista