Introduction:
I have a C++ project inside the Qt framework, and I have recently created a CAN-bus SAE J1939 library in pure 100% C99 code. The library works very well. I will now import the library into my Qt project in Qt Creator.
Note: The compiler is MinGW 5.15.2
Method:
I have included .h files in C++ with Qt framework by including the line inside my .pro project file.
include(ThirdLibrary/OpenSAEJ1939/OpenSAEJ1939.pri)
Inside the OpenSAEJ1939.pri
file, it is written
INCLUDEPATH += $$PWD
Here is my project folder:
The path ThirdLibrary/OpenSAEJ1939/Open_SAE_J1939/
So when I created a C++ source file and then added the C source function, I got undefined reference to Open_SAE_J1939_Listen_For_Messages.
#include "Can_Bus_Listen_Thread.h"
CAN_Bus_Listen_Thread::CAN_Bus_Listen_Thread(J1939* j1939, bool* usbMessageAvailable, bool* startCANBusListenThread){
this->j1939 = j1939;
this->usbMessageAvailable = usbMessageAvailable;
this->startCANBusListenThread = startCANBusListenThread;
}
void CAN_Bus_Listen_Thread::run(){
while(1){
if(*this->startCANBusListenThread && *this->usbMessageAvailable)
Open_SAE_J1939_Listen_For_Messages(this->j1939);
msleep(1);
}
}
I look inside the C++ header Can_Bus_Listen_Thread.h and I can see that I have imported the C header file from ThirdLibrary/OpenSAEJ1939/Open_SAE_J1939/.
#ifndef CAN_BUS_LISTEN_THREAD_H
#define CAN_BUS_LISTEN_THREAD_H
#include <QThread>
#include <QtSerialPort>
#include "ThirdLibrary/OpenSAEJ1939/Open_SAE_J1939/Open_SAE_J1939.h"
class CAN_Bus_Listen_Thread : public QThread {
public:
CAN_Bus_Listen_Thread(J1939* j1939, bool* usbMessageAvailable, bool* startCANBusListenThread);
private:
J1939* j1939;
bool* startCANBusListenThread;
bool* usbMessageAvailable;
void run();
};
#endif // CAN_BUS_LISTEN_THREAD_H
I have successfully included the C
header files, but these header files cannot find the C
source files. And yes, the Open_SAE_J1939_Listen_For_Messages
is surrounded with extern "C" { }
here inside Open_SAE_J1939.h.
Have I forgot something? C++ should be able to read C source files if they are surrounded with extern "C" { }
#ifndef OPEN_SAE_J1939_OPEN_SAE_J1939_H_
#define OPEN_SAE_J1939_OPEN_SAE_J1939_H_
/* Layers */
#include "../Open_SAE_J1939/Structs.h"
#include "../SAE_J1939/SAE_J1939-71_Application_Layer/Application_Layer.h"
#include "../SAE_J1939/SAE_J1939-73_Diagnostics_Layer/Diagnostics_Layer.h"
#include "../SAE_J1939/SAE_J1939-81_Network_Management_Layer/Network_Management_Layer.h"
#ifdef __cplusplus
extern "C" {
#endif
/* This functions must be called all the time, or be placed inside an interrupt listener */
void Open_SAE_J1939_Listen_For_Messages(J1939 *j1939);
#ifdef __cplusplus
}
#endif
#endif /* OPEN_SAE_J1939_OPEN_SAE_J1939_H_ */
Here is the solution.
.c
and .h
files inside the .pro
file.Hint: Don't use ../../
. That can cause troubles. Instead, use the project path instead, e.g.,
"ThirdLibrary/OpenSAEJ1939/...your_h_files.h"
You don't need the .pri
file. Get rid of it.