2

I have an external library written in C++ such as

external.h

#ifndef OUTPUT_FROM_CPP_H
#define OUTPUT_FROM_CPP_H

#include <cstdint>
extern "C" uint8_t myCppFunction(uint8_t n);

#endif

external.cpp

#include "external.h"
uint8_t myCppFunction(uint8_t n)
{
    return n;
}

Currently I have no choice but use this C++ library in my current C project. But my compiler is telling me

No such file or director #include <cstdint>

when used in my C project

main.c

#include "external.h"

int main()
{
    int a = myCppFunction(2000);

    return a;
}

I understand that this is because cstdint is a C++ standard library that I'm trying to use through my C file.

My questions are:

  • Is there a way I can manage to use this C++ library in my C project without modifying my libary ?
  • If no, what whould I have to do on the library side to make it possible ?
LPo
  • 45
  • 4

4 Answers4

2

The c prefix in cstdint is because it's really a header file incorporated from C. The name in C is stdint.h.

You need to conditionally include the correct header by detecting the __cplusplus macro. You also need this macro to use the extern "C" part, as that's C++ specific:

#ifndef OUTPUT_FROM_CPP_H
#define OUTPUT_FROM_CPP_H

#ifdef __cplusplus
// Building with a C++ compiler
# include <cstdint>
extern "C" {
#else
// Building with a C compiler
# include <stdint.h>
#endif

uint8_t myCppFunction(uint8_t n);

#ifdef __cplusplus
}  // Match extern "C"
#endif

#endif
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • This is the only answer (as I write this) that doesn't either require creation of separate header files for C and C++, and therefore create a long-term maintenance headache where two files have to be kept in sync; or forces C++ code to depend on `stdint.h` instead of `cstdint` - [those two headers are **not** exactly equivalent](https://stackoverflow.com/questions/10460250/cstdio-stdio-h-namespace). – Andrew Henle May 10 '22 at 09:34
0

You have to modify the library.

Replace <cstdint> with <stdint.h>. Normally the former is recommended, but only the latter exists in C.

You should also be getting errors on extern "C". That's solved by putting following right below the includes:

#ifdef __cplusplus
extern "C" {
#endif

With a matching section at the end of file:

#ifdef __cplusplus
}
#endif

Then extern "C" can be removed from individual functions.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
0

Is there a way I can manage to use this C++ library in my C project without modifying my libary ?

Create a separate header that is portable with C and use that header when compiling with C compiler:

// external_portable_with_c.h
// rewrite by hand or generate from original external.h
// could be just sed 's/cstdint/stdint.h/; s/extern "C"//'
#include <stdint.h>
uint8_t myCppFunction(uint8_t n);
 
// c_source_file.c
#include "external_portable_with_c.h"
void func() {
    myCppFunction(1);
}

If no, what whould I have to do on the library side to make it possible ?

Is answered by other answers. Protect the C++ parts with #ifdef __cplusplus.

Note that (some? all?) compilers require the main function to be compiled with C++ compiler for C++ and C to work together properly. https://isocpp.org/wiki/faq/mixing-c-and-cpp#overview-mixing-langs

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
0

If you don't want to modify the library header, create a new file, for example includes_for_cpp/cstdint with content

#include <stdint.h>

Add the directory includes_for_cpp to the include path of your C project. After that, #include <cstdint> should find your file.

VLL
  • 9,634
  • 1
  • 29
  • 54