-1

I have a small issue.

I thought that using using extern "C" will turn the C code into C++ code directly.

#ifdef __cplusplus
extern "C" {
#endif

ENUM_J1939_STATUS_CODES CAN_Send_Message(uint32_t ID, uint8_t data[], uint8_t delay);
ENUM_J1939_STATUS_CODES CAN_Send_Request(uint32_t ID, uint8_t PGN[], uint8_t delay);
bool CAN_Read_Message(uint32_t *ID, uint8_t data[]);

#ifdef __cplusplus
}
#endif

But when I placed a class QSerialPort in here

#ifdef __cplusplus
extern "C" {
#endif
#include <QSerialPort>
ENUM_J1939_STATUS_CODES CAN_Send_Message(uint32_t ID, uint8_t data[], uint8_t delay);
ENUM_J1939_STATUS_CODES CAN_Send_Request(uint32_t ID, uint8_t PGN[], uint8_t delay);
bool CAN_Read_Message(uint32_t *ID, uint8_t data[]);

#ifdef __cplusplus
}
#endif

Then I got 500 errors about data types, name space and all kind of C++ keywords that C does not have.

Question:

In QT. I have to make sure that I can use a C++ class inside a .h file and the .h is included inside a .c file. But right now, my QT IDE shows me 500 errors if I do that.

Is there a way for C code to call C++ code or turning the C code into 100% C++ code, whithout renaming the files .c to .cpp?

My goal is to use C++ features from C, by using extern "C" inside the header of the .c file, but it isin't going any well for me.

Edit:

I tried some ways and this does not work. I get 500 errors.

#include <QSerialPort>

#ifdef __cplusplus
extern "C" {
#endif

void QT_USB_set_serial_handler(QSerialPort* serial_port);
ENUM_J1939_STATUS_CODES QT_USB_Transmit(uint32_t ID, uint8_t data[], uint8_t DLC);
void QT_USB_Get_ID_Data(uint32_t *ID, uint8_t data[], bool* is_new_message);

#ifdef __cplusplus
}

This gives only one error.

#ifdef __cplusplus
#include <QSerialPort>
extern "C" {
#endif

void QT_USB_set_serial_handler(QSerialPort* serial_port); <-- complaining here on QSerialPort keyword
ENUM_J1939_STATUS_CODES QT_USB_Transmit(uint32_t ID, uint8_t data[], uint8_t DLC);
void QT_USB_Get_ID_Data(uint32_t *ID, uint8_t data[], bool* is_new_message);

#ifdef __cplusplus
}

This gives no error at all.

#ifdef __cplusplus
#include <QSerialPort>
void QT_USB_set_serial_handler(QSerialPort* serial_port);
extern "C" {
#endif

ENUM_J1939_STATUS_CODES QT_USB_Transmit(uint32_t ID, uint8_t data[], uint8_t DLC);
void QT_USB_Get_ID_Data(uint32_t *ID, uint8_t data[], bool* is_new_message);

#ifdef __cplusplus
}
euraad
  • 2,467
  • 5
  • 30
  • 51
  • 5
    It's forcing C++ to generate identifiers usable by C code. [Helpful reading](https://en.wikipedia.org/wiki/Name_mangling) – user4581301 Aug 17 '21 at 23:09
  • It is straightforward to call C code from a program that's predominantly written in C++. It is *not* straightforward (personally I believe it's generally impossible) to call C++ code from a program that's predominantly written in C. – Steve Summit Aug 17 '21 at 23:22

1 Answers1

8

You use extern "C" { ... } in C++ code, around declarations of external functions which are C functions, not C++ functions.

extern "C" { ... } does not somehow "turn C code into C++ code".
It does not turn C++ code into C code, either.

You use extern "C" { ... } when you have some other function(s) to call, and those other functions are present in source files ending in .c and compiled as C, not C++. extern "C" { ... } makes sure that your C++ compiler passes arguments, generates function calls, emits relocation information, etc., in a way that's compatible with C, not C++.

There's no mechanism (that I know of) to embed arbitrary C code inside a C++ source file, and have it treated as C. And there's even less of a mechanism to embed arbitrary C++ code inside a C source file, and have it treated as C++!


Addendum: I'm somewhat embarrassed that this answer has been upvoted and accepted, since I've just realized it's been only partially correct so far. extern "C" can indeed be used to mark an external function (defined elsewhere) as being named and called using C conventions, as I said. But it can also be used to mark a C++ function (defined "here") as being named and called using C conventions, so that it can be called from a C function elsewhere.

See this other answer for a better explanation of this.

To summarize, I believe there are two almost completely different cases using extern "C":

syntax function defined function written in function called from caller written in
function declaration somewhere else C (or maybe C++) here C++
function definition here C++ somewhere else C or C++

In particular, you can call a C function from C++ (first row, the case I was talking about above), but you can also call a C++ function from C (second row, that I tend to forget is even possible). In the second case, when you're calling a C++ function from C, I think you have to make sure that your final compilation uses a C++ compiler, not a C compiler, so that the right run-time support will be provided for the C++ functions that need it.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • Yes. I'm using extern "C" correctly, but I think I need another solution if I want to use C++ features inside the C code. – euraad Aug 17 '21 at 23:15
  • 1
    But imagine.... `extern "Pascal" { (* Pascal code goes here *) }`, and `extern "BASIC" { REM Basic code goes here }` and `extern "FORTRAN" { C FORTRAN code goes here }` and `extern "Brainf" { +[-->-[>>+>-----<<]<--<---]>-.>>>+.>>..+++[.>]<<<<.+++.------.<<-.>>>>+. }` ... the pain is endless! – Eljay Aug 17 '21 at 23:16
  • 2
    _I want to use C++ features inside the C code._ Then wrap them in free functions, declared as `extern "C"`. – Paul Sanders Aug 17 '21 at 23:18
  • @PaulSanders You mean between `#ifdef __cplusplus` and `#endif` ? – euraad Aug 17 '21 at 23:25
  • Yes, if you're going to include the same header file in both C and C++ source files (which would be the recommended way). – Paul Sanders Aug 17 '21 at 23:27
  • 2
    @MrYui "*I want to use C++ features inside the C code*" - that will never work, since a C compiler is not a C++ compiler. But what you can do instead is put the C++ code into an external DLL library that exports the necessary functionality as C-style functions that are wrapped in `extern "C"`. Then the C code can use those DLL functions as needed. – Remy Lebeau Aug 18 '21 at 00:10
  • @RemyLebeau Thank you for that suggestion. I don't know how to create a DLL file. But I think I solved it above in my edited question. – euraad Aug 18 '21 at 00:18