سؤال

I have a (large) C/C++ project that consists of both C and C++ languages. At some point it turned out that there are two C functions with identical names. Those functions are defined in two different *.c files in different locations. In general at the highest level, the project is C++. This problem was questioned and answered here

However still a question "how to organize those files safely" remains. How can I group such project so that there are no name conflicts, and I can be sure that proper function is called. Will writing a wrapper for each of those functions help?

That how it looks at the moment: A.h //first declaration of function F A.c //first definition of function F

B.h //second declaration of function F B.c //second definition of function F

trying to make such thing:

extern "C"{
#include "A.h"
#include "B.h"
}

causes of course name conflict. What can I do to avoid this conflct, and have the robust code? Would such solution help:

A_Wrapper.h: //c++

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

void WrapF_A(int x)
{
  F(x);
}

B_Wrapper.h: //C++

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

void WrapF_B(int x)
{
  F(x);
}

and then in the program:

#include A_Wrapper.h
#include B_Wrapper.h

Modyfing each file in that project would be rather impossible as it cosists of hundreds of files, and i would probably damage some code rather. Is there a way to make an include file seen only in some part of the program?

EDIT: So I created a simple project illustrating the problem, and tried to apply the hints given by doctorlove. However still multiple definition of F error occurs. What should I change? Project files:

A.h:

#ifndef A_H_INCLUDED
#define A_H_INCLUDED

int F(int x);

#endif // A_H_INCLUDED

A.c

#include "A.h"

int F(int x)
{
   return x*x;
}

AWrapper.h:

#ifndef AWRAPPER_H_INCLUDED
#define AWRAPPER_H_INCLUDED

int AF(int x);

#endif // AWRAPPER_H_INCLUDED

AW.cpp:

#include "AWrapper.h"
extern "C"{
#include "A.h"
}

int AF(int x)
{
   return F(x);
}

B.h:

#ifndef B_H_INCLUDED
#define B_H_INCLUDED

int F(int x);

#endif // B_H_INCLUDED

B.c:

#include "B.h"

int F(int x)
{
   return -x*x;
}

BWrapper.h:

#ifndef BWRAPPER_H_INCLUDED
#define BWRAPPER_H_INCLUDED

int BF(int x);

#endif // BWRAPPER_H_INCLUDED

BW.cpp:

#include "BWrapper.h"
extern "C"{
#include "B.h"
}

int BF(int x)
{
   return F(x);
}
هل كانت مفيدة؟

المحلول

Go with your wrapper idea, but write a facade (see also here) that exposes what you need from A, and what you need from B not all the functions in there.

You will end up with something like

//header Wrap_A.h
#ifndef WRAP_A_INCLUDED
#define WRAP_A_INCLUDED

//for some input Data left as an exercise for the reader...
double solve_with_A(Data data);

#endif


//header Wrap_B.h
#ifndef WRAP_B_INCLUDED
#define WRAP_B_INCLUDED

//for some input Data...
double solve_with_B(Data data);

#endif

Then make two cpp files that include all the conflicting headers files, those from A in A.cpp and those from B in B.cpp, so the conflicts don't happen. The solve_with_A and solve_with_B functions will then call all the things they need without without leaking them to the whole program and causing conflicts.

You might have to give some thought to what Data will actually be. You could define your own types, one for A and one for B. Just avoid exposing the implementation details in your wrapping/facade headers.
If headers are causing you pain, firewall them off in the naughty corner.


EDIT

Given you have two functions, F, if you put all the sources into one project the linker should and will complain it can see both. Instead, you need to make two static libraries, and just expose the wrapped version to your main project.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top