10 years, 9 months ago.

Unexpected linker errors

Hi all,

I'm messing from about 3 days with some strange errors coming out while trying to compile a program with some classes in different files (see code in the bottom)... I can't find any information about my problem.

Problem

My program wont compile: I get some errors like the following one (from the online compiler): " Undefined symbol ESC::pulse() (referred from main.cpp.LPC1768.o)." in file "/" (Error Number: L6218E)

What I verified

This may seem to you as a common mistake like file/header not included or typoed name - and I think it is a simple mistake, just because (I'm quite expert in C++ oop, but) I'm new to the mbed IDE - BUT (as you may confirm reading my code below):

  • I double-checked all the names are correctly typed;
  • all the needed libraries are imported into the program;
  • there are no syntax errors (the compiler says);
  • nothing better if I convert libraries to folders;
  • I think that I had correctly #included the needed files, just like I always did outside mbed and like other users do.

Context

The above error comes out from a call of esc1.pulse() inside main()... esc1 is an ESC object; the ESC class is defined in the esc.h file in the ESC library; the ESC::pulse() method is defined in the esc.cpp file that is in the same ESC library; in the esc.cpp file is #included the esc.h file, that is #include#d in //main.cpp//.

so...

(I also tryed using ARM gcc but, for other reasons, I can't make the toolchain work)

Need more precisations about my problem?

I will thank you very much if you help me finding my stupid (?) mistake.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Code

This is the program I'm working on - the main control software for a quadrotor. It doesn't work.

Import programMTQuadControl

Work in progress...

This is the imported library that I mentioned above.

Import libraryESC

ESC class used to controll standard Electronic Speed Controllers for brushless motors of RC models

1 Answer

10 years, 9 months ago.

Hi,

You can remove 'inline' keyword for both esc.h and esc.cpp to avoid the error. If you need to inline the function, you have to place your function definition into header file (esc.h), not source file (esc.cpp).

I hope this helps.

Regards, Toyomasa Watarai

Accepted Answer

Thanks for the answer. I removed all the inline keywords from all my code and the error about ESC::pulse() is magically disappeared, but other errors of the same type are still there:

  • " Undefined symbol SharedObject<float>::SharedObject(const float&) (referred from main.cpp.LPC1768.o)." in file "/"
  • " Undefined symbol RefRX::_ref1_ptr (referred from RefRX.cpp.LPC1768.o)." in file "/"
  • 5 other errors of the same type...

maybe I made a lot of different mistakes that produce the same error..?

posted by Matteo Terruzzi 19 Jul 2013

Hi,

Definition of member functions of class template must be in the header file.

Therefore, in your SharedObject.h file has to be:

template <class T>
class SharedObject
{

    /** get/set controll mutex
     */
    Mutex _readwrite_mutex;

    /** value of the object
     */
    T _value;

public:

    /** Resource constructor.
     *  @param value sets the initial value of the resource.
     */
    SharedObject (const T& value)
    {
        _readwrite_mutex.lock();
        _value = value;
        _readwrite_mutex.unlock();
    }

posted by Toyomasa Watarai 19 Jul 2013

Also, static member has to be instanced globally somewhere in you source code. For example:

#include "RefRX.h"

Thread RefRX::_RX_thread = 0;
SharedObject<uint32_t>* RefRX::_ref1_ptr = 0;
SharedObject<uint32_t>* RefRX::_ref2_ptr = 0;
SharedObject<uint32_t>* RefRX::_ref3_ptr = 0;
SharedObject<uint32_t>* RefRX::_ref4_ptr = 0;

void RefRX::init (const unsigned short listen_port,
        const unsigned short destination_control_port,
        SharedObject<uint32_t>* ref1,
        SharedObject<uint32_t>* ref2,
        SharedObject<uint32_t>* ref3,
        SharedObject<uint32_t>* ref4 )
{
    _RX_thread = Thread(&RefRX::_RX_thread_cycle);
    _ref1_ptr = ref1;
    _ref2_ptr = ref2;
    _ref3_ptr = ref3;
    _ref4_ptr = ref4;
}
posted by Toyomasa Watarai 19 Jul 2013

OK, I didn't study enough. All the errors are now resolved.

Thank you very much for your attention!

posted by Matteo Terruzzi 19 Jul 2013