Home > Software design >  Calling C standard header (cstdint) from C file
Calling C standard header (cstdint) from C file

Time:05-10

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 ?

CodePudding user response:

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

CodePudding user response:

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.

CodePudding user response:

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

CodePudding user response:

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.

  • Related