使用ARM mbed的回调时未定义的引用

时间:2016-10-21 09:15:23

标签: c++ callback linker function-pointers mbed

上下文:我正在为一个名为Switch的InterruptIn做一个开关去抖动包装器类。切换将允许用户附加他们自己的功能,当按下并去抖动真实世界的开关时,该功能应该被回叫。我使用Eclipse C ++和arm-none-eabi- *工具链。

首先,我找到了三种用mbed实现回调的方法:

  1. FunctionPointer类,由ARM弃用,但是has some documentation(我认为我需要的信息的超链接已断开)。

  2. Callback< void()>,编译器在尝试使用弃用的FunctionPointer时,通知我这是正确的方法 TM 进行回调,但没有文档?

    < / LI>
  3. event_callback_t,没有文档,负责调用用户附加函数的函数将int作为参数?

  4. 我将使用Callback&lt; void()&gt;显示我遇到的问题的方法,但所有三种方法都会产生相同的编译错误。

    Switch.h:

    #ifndef MBED_SWITCH_H
    #define MBED_SWITCH_H
    
    #include "mbed.h"
    
    class Switch {
        private:
            Callback<void()> callback_press_;
            InterruptIn switch_;
    
            //redacted some debouncing stuff
    
        public:
            Switch(PinName pin, bool isActiveHigh);
            Switch(PinName pin, bool isActiveHigh, int samplePeriod_us, int sampleCount);
    
            void attachPress(Callback<void()>); //THE PROBLEM FUNCTIONS
            template<typename T, typename F>
            void attachPress(T* object, F function);
    };
    
    #endif
    

    Switch.cpp:

    #include "Switch.h"
    #include "CustomNames.h"
    
     // redacted constructors here
    
     //  redacted debouncing functions here
    
     // for attaching a function not associated with any particular class
    void Switch::attachPress(Callback<void()> function) {
        callback_press_.attach(function);
    }
    
     // for attaching a member function of some other class
    template<typename T, typename F>
    void Switch::attachPress(T* object, F function) {
        callback_press_.attach(object, function);
    }
    

    问题

    如果我使用第一个候选函数attachPress(Callback&lt; void()&gt;函数)来附加与任何特定类无关的函数,那么在现实世界中,所有内容都会编译,链接和工作正常。

    但是,当我尝试附加特定的成员函数&#34; testfunc1(void)&#34;另一个班级&#34;测试&#34;使用第二个候选函数,我得到以下错误(来自链接器,我认为):

    Test.o: In function `Test::Test()':
    Test.cpp:(.text._ZN4TestC2Ev+0x1e): undefined reference to `void Switch::attachPress<Test, void (Test::*)()>(Test*, void (Test::*)())'
    /home/yankee/programming_projects/cpp-eclipse/SO_EXAMPLE/Makefile:97: recipe for target 'HW4_RACE.elf' failed
    collect2: error: ld returned 1 exit status
    Makefile:21: recipe for target 'all' failed
    make[1]: *** [HW4_RACE.elf] Error 1
    make: *** [all] Error 2
    
    03:10:35 Build Finished (took 165ms)
    

    为什么这会给我&#34;未定义的引用&#34;,有没有办法解决它?

1 个答案:

答案 0 :(得分:2)

模板化的类和函数在使用之前不会被实例化。

这意味着,使用模板类和函数的翻译单元需要该模板的完整代码。

在这种情况下,只需移动:

template<typename T, typename F>
void Switch::attachPress(T* object, F function) {
    callback_press_.attach(object, function);
}

Switch.cppSwitch.h即可。