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.

5
  • You shouldn't include c headers(stdxxxx.h) in c++ programs. Use c++ version of them instead (cstdxxxx). Commented Feb 9, 2016 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. Commented Feb 9, 2016 at 14:00
  • 2
    Not necessarily, cmath/cstring... are all available since C++98 Commented Feb 9, 2016 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 ? Commented Feb 9, 2016 at 14:42
  • @ecatmur: The compiler says: error: ‘printf’ in namespace ‘fw’ does not name a type. Commented Feb 9, 2016 at 15:04

1 Answer 1

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_;
Sign up to request clarification or add additional context in comments.

4 Comments

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".
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 experience, mostly - only the preprocessor can confuse a compiler enough that it reads fw::ipc::A as fw::printf::<something>. Raymond Chen calls this "psychic debugging".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.