2

I already looked at the following two posts on the same topic: Post1 Post2. I have a similar problem but not the same (I guess). So posting it here. Sorry if it is still a duplicate.

I have a C-static library(libComm.a) which contains the implementation for the following ..

comm.h:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <math.h>
.....
typedef struct _CDef {} CommDef;

And I get this file delivered. I cannot change it in anyway. Apart from this I also have another Cpp library (libfw.a):

fw.h:

namespace fw { namespace ipc {
class A { ...... };
} }

My aim is to use both the libraries in my C++ application:

myCppApp.cpp

#include "fw.h"
extern "C" {
#include "comm.h"
}

namespace chat { namespace comm {
class CppApplication
{
private:
   CommDef def;
   fw::ipc::A ipc;
};
}
}

When I want to compile this, the compiler cannot find, "fw::ipc::A". But if I do not use the C header and the corresponding data type, everything works fine.

I realized this is because the header file I am including contains standard C include files. So, my question is how can I solve this compile issue and at the end link successfully to the lib, with the following conditions:

  1. Without changing the delivered sources
  2. Without using C++11 to include the corresponding CPP definitions because of point-1

Many thanks for your time.

Community
  • 1
  • 1
PSN
  • 23
  • 3
  • You shouldn't include c headers(`stdxxxx.h`) in c++ programs. Use c++ version of them instead (`cstdxxxx`). – user3528438 Feb 09 '16 at 13:56
  • That is not an option to me because they are defined in C++ 11 only, and I cannot use C++11 due to internal performance and other portability issues. – PSN Feb 09 '16 at 14:00
  • 2
    Not necessarily, `cmath`/`cstring`... are all available since C++98 – user3528438 Feb 09 '16 at 14:03
  • Hmmm .. Thanks for the quick answer. But it still does not solve my first requirement of not able to change the delivered sources. It is not simply one single file. The library I am talking about contains hundreds of files and I am afraid I might have to change all of these. And when the new version of the library is delivered, I again have to do the same. This makes me believe that it is not possible without me changing the delivered sources ? – PSN Feb 09 '16 at 14:42
  • @ecatmur: The compiler says: error: ‘printf’ in namespace ‘fw’ does not name a type. – PSN Feb 09 '16 at 15:04

1 Answers1

2

The problem is that the C header is polluting the preprocessor with #defines. One possibility is to clean up afterwards using #undef:

extern "C" {
#include "comm.h"
}
#undef ipc
// ...

The other option is to add aliases for names that the C header makes inaccessible, before including it:

#include "fw.h"
typedef fw::ipc::A fw_ipc_A;
extern "C" {
#include "comm.h"
}
// ...
fw_ipc_A ipc_;
ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • Thanks for the answer. I tried the second proposal and that solved the issue. But could you please elaborate on what you mean by the following for my understanding: "Polluting the preprocessor with define's". – PSN Feb 09 '16 at 15:18
  • @PSN see http://stackoverflow.com/questions/30742148/why-is-it-not-advised-to-define-macros-in-header-files?rq=1 – ecatmur Feb 09 '16 at 15:23
  • I understand that and I totally agree to it. And indeed the C-library I was using, had hundreds of defines. Sorry for not being specific in my previous comment, but what I wanted to understand is how you came to this conclusion of what is wrong, simply looking at the error message which itself is anything other than self explanatory. Thanks again. – PSN Feb 09 '16 at 15:39
  • @PSN experience, mostly - only the preprocessor can confuse a compiler enough that it reads `fw::ipc::A` as `fw::printf::`. Raymond Chen calls this "psychic debugging". – ecatmur Feb 09 '16 at 15:47