0

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:

Enter image description here

The path ThirdLibrary/OpenSAEJ1939/Open_SAE_J1939/

Enter image description here

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_ */
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
euraad
  • 2,467
  • 5
  • 30
  • 51
  • Have you added the library to the compile command? This error doesn't seem as if something wasn't included, but rather that the library defining that something is not linked. An other worrying thing is that it seems that you work with windows, but `__declspec(dllimport)` is not used. In that case the sources should be compiled as well and linked against/ static library should be used – Lala5th Aug 17 '21 at 11:42
  • @Lala5th Thank you for your reply. `Have you added the library to the compile command?` -> No, I don't know how to do that. `An other worrying thing is that it seems that you work with windows` -> Yes, Windows is horror. It's always something it complains about. `sources should be compiled as well and linked against/ static library should be used` -> Yes, but the QT IDE gives me errors about "undefined reference" to C-files that are surrounded with `Extern "C"` – euraad Aug 17 '21 at 12:12
  • I may have missed it here, but I do not see what compiler you are using. Regardless, there will be compiler specific documentation on how to link a library, you can learn how there. If you are using gcc, an [example is here](https://stackoverflow.com/a/6016851/645128) – ryyker Aug 17 '21 at 12:28
  • This might help if `OpenSAEJ1939` is a compiled library https://stackoverflow.com/questions/718447/adding-external-library-into-qt-creator-project, otherwise you should add the sources to be compiled as well. As to the error, it seems that the IDE recognises linker errors as well and that it isn't triggered by the lack of declaration in a header file, but rather by the lack of libraries defining the function. – Lala5th Aug 17 '21 at 12:29
  • @ryyker I'm using MinGW 5.15.2 compiler. – euraad Aug 17 '21 at 12:31
  • MinGW includes a port of the GNU Compiler Collection (GCC), so yes, you are using gcc. (I placed that information in your post.) Did you look at/try what the link said? – ryyker Aug 17 '21 at 12:34
  • @ryyker I haven't done that. I will try. Where should I add the linker `-l` in QT? – euraad Aug 17 '21 at 12:36
  • @ryyker Sorry. I'm using QT 5.15.2 and MinGW 64-bit 8.1. – euraad Aug 17 '21 at 12:40
  • _"Where should I add the linker -l in QT?"_... You don't. `-l` is a compiler switch to link a library during the build. It will be part of the compiler command if you are using command line. If you are using an IDE, such as Code::Blocks, or Eclipse, then read the documentation to include the library under compiler/linking methods for that environment. – ryyker Aug 17 '21 at 12:41
  • @ryyker So you think that's the issue for me, I haven't link the source `C` files? – euraad Aug 17 '21 at 12:45
  • @ryyker I'm using QT Creator – euraad Aug 17 '21 at 12:48
  • It is not perfectly clear what the issue is. There may be more than one. The message: _"undefined reference to `Open_SAE_J1939_Listen_For_Messages`"_ could be a missing source file, or library. I only focused on library as follow-up on previous comments. – ryyker Aug 17 '21 at 12:48
  • _"I'm using QT Creator "_. Then you need to become familiar with how to set up that environment. That can only be done through spending time in the documentation, [this section for example.](https://doc.qt.io/qtcreator/creator-tool-chains.html) – ryyker Aug 17 '21 at 12:51
  • @ryyker The source file is not missing. I can see it inside the folders. – euraad Aug 17 '21 at 12:52
  • @ryyker I have successfully imported all .c and .h files now and the IDE does not warns me about undefined reference. But...some of the .h files can the IDE not find. I don't know why. – euraad Aug 17 '21 at 13:09
  • `#include "../../ISO_11783/ISO_11783_Enums/Enum_Auxiliary_And_General_Purpose_Valves.h"` no such file or dictionary. Can this be a classical compiler issue, that the name is too long? – euraad Aug 17 '21 at 13:10
  • @ryyker No issue there. I just right click on my project -> Import new folder and then I selected my ThirdLibrary folder. Bam...all files included. I have been told by QT experts to import files on the method I did above. Told them it did not work "It has to work!" they said. – euraad Aug 17 '21 at 13:12
  • Does QT have the [ability to interface with C libraries](https://stackoverflow.com/a/1729205/645128)? – ryyker Aug 17 '21 at 13:35
  • 1
    @ryyker I think I got it....It seems that the issue is not QT, instead its `"../../` that causing problems. – euraad Aug 17 '21 at 13:37
  • @ryyker Also I removed the `.pri` file because it's useless. – euraad Aug 17 '21 at 13:38

1 Answers1

0

Here is the solution.

  1. right-click on your project in Qt.
  2. Select "Add existing dictionary"
  3. Mark the dictionary you want to import. Now you are seeing lots of .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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
euraad
  • 2,467
  • 5
  • 30
  • 51