调用模板提供的(静态)函数

问题描述 投票:1回答:2

我正试图为一个叫做 任务.这里的挑战是,freertos需要采取一个 函数指针https:/www.freertos.orgxTaskCreateStatic.html

现在我想到了这个

template<typename Functor_T, uint32_t u32StackSize>
class CFreeRTOS_Task
{
public:
    ///Constructor
    CFreeRTOS_Task(const std::string& strTaskNameArg);
    ///Destructor
    ~CFreeRTOS_Task();

private:
    ///the Name of this task
    const std::string strTaskName;
    ///the task handle
    TaskHandle_t task;
    ///the task control block
    StaticTask_t task_tcb;
    ///is the task currently running (can be accessed from multiple threads => atomic)
    std::atomic<bool> bTaskRunning;
    ///the actual stack
    StackType_t stack[u32StackSize] = {};
    ///the task function to pass to freertos
    static void TaskFunction(void* pvParameters);
};

//+++++++++++++++++++++++++  Implementation +++++++++++++++++++++++++++++++++++++++++
template<typename Functor_T, uint32_t u32StackSize>
CFreeRTOS_Task<Functor_T, u32StackSize>::CFreeRTOS_Task(const std::string& strTaskNameArg) :
    strTaskName(strTaskNameArg)
{
    task = xTaskCreateStatic(
        TaskFunction, /* Function that implements the task. */
        strTaskName.c_str(), /* Text name for the task. */
        u32StackSize, /* Number of indexes in the xStack array. */
        (void*)1, /* Parameter passed into the task. */
        tskIDLE_PRIORITY,/* Priority at which the task is created. */
        stack, /* Array to use as the task's stack. */
        &task_tcb); /* Variable to hold the task's data structure. */
    bTaskRunning = true;
}
template<typename Functor_T, uint32_t u32StackSize>
CFreeRTOS_Task<Functor_T, u32StackSize>::~CFreeRTOS_Task()
{
    if (bTaskRunning)
    {
        //terminate task...
        bTaskRunning = false;
    }
}
template<typename Functor_T, uint32_t u32StackSize>
void CFreeRTOS_Task<Functor_T, u32StackSize>::TaskFunction(void* pvParameters)
{
    //do some initilisation
    for (;;)
    {
        //call the user provided task function
        Functor_T();
        osDelay(10);
    }
    //shutdown this task (common to all freertos tasks)
}

现在我的实例化是这样的

///test task function
static void TestTaskFunc();


///Test task instance
static CFreeRTOS_Task<TestTaskFunc,10> testTask("test_task");


static void TestTaskFunc()
{
    volatile uint32_t test = 0;
}

但是我得到了2个编译器错误

error: type/value mismatch at argument 1 in template parameter list for 'template<class Functor_T, long unsigned int u32StackSize> class NRTOS_Wrapper::CFreeRTOS_Task'
static CFreeRTOS_Task<TestTaskFunc,10> testTask("test_task");
                                      ^
note:   expected a type, got 'NRTOS_Wrapper::TestTaskFunc'
error: invalid conversion from 'const char*' to 'int' [-fpermissive]

你能帮我找出我缺少什么吗?

c++ c++11 templates function-pointers freertos
2个回答
3
投票

你的类模板的写法。Functor_T 是一个 类型 不是 价值. 有几个地方你已经被它绊住了。

static CFreeRTOS_Task<TestTaskFunc,10> testTask("test_task");

在这里,你试图传递一个值,在这里 CFreeRTOS_Task 正在期待一个类型。

template<typename Functor_T, uint32_t u32StackSize>
void CFreeRTOS_Task<Functor_T, u32StackSize>::TaskFunction(void * pvParameters)
{
    //do some initilisation
    for(;;)
    {
        //call the user provided task function
        Functor_T();   // <---- HERE
        osDelay(10);
    }

    //shutdown this task (common to all freertos tasks)
}

在这里,你正在对一个类型为 Functor_T,而不是像评论中所说的那样调用一个现有的漏斗对象。 类似于 Functor_T()() 对于函数对象来说可能是有意义的,但如果说 Functor_T 是一个简单的函数指针类型(就像你的例子一样),这没有任何意义。


看起来你实际需要做的是存储一个 对象 类中的漏斗类型,然后将一个指向该对象的指针传递给 TaskFunction. 例如,在你的通话现场,给你的电话。

template<typename Functor_T, uint32_t u32StackSize>
class CFreeRTOS_Task
{
public:
    ///Constructor
    CFreeRTOS_Task(std::string strTaskNameArg, Functor_T functor);
private:
    //...

    using Func_T = std::decay_t<Functor_T>;
    ///the functor to call
    Func_T mFunctor;

    ///the task function to pass to freertos
    static void TaskFunction(void* pvParameters);

};

template<typename Functor_T, uint32_t u32StackSize>
CFreeRTOS_Task<Functor_T, u32StackSize>::CFreeRTOS_Task(
    std::string strTaskNameArg,
    Functor_T functor
)
    : strTaskName{std::move(strTaskNameArg)},
      mFunctor{std::move(functor)}
{
    task = xTaskCreateStatic(
        TaskFunction, /* Function that implements the task. */
        strTaskName.c_str(), /* Text name for the task. */
        u32StackSize, /* Number of indexes in the xStack array. */
        &mFunctor, /* The functor to call, passed as a parameter into the task. */
      //^^^^^^^^^^ <---- HERE, pass a pointer to the functor as the task arg
        tskIDLE_PRIORITY,/* Priority at which the task is created. */
        stack, /* Array to use as the task's stack. */
        &task_tcb /* Variable to hold the task's data structure. */
    );
    bTaskRunning = true;
}

template<typename Functor_T, uint32_t u32StackSize>
void CFreeRTOS_Task<Functor_T, u32StackSize>::TaskFunction(void * pvParameters)
{
    //do some initilisation
    for(;;)
    {
        //cast the parameter back to a pointer to the correct functor type
        Func_T* pFunctor = reinterpret_cast<Func_T*>(pvParameters);
        //call the user provided task function
        (*pFunctor)();
        osDelay(10);
    }

    //shutdown this task (common to all freertos tasks)
}

然后在你的通话地点,给 类型 的漏斗,作为你的 CFreeRTOS_Task的模板参数,并将 价值 的构造函数。

///test task function
static void TestTaskFunc();


///Test task instance
static CFreeRTOS_Task<decltype(TestTaskFunc),10> testTask("test_task", TestTaskFunc);
                    //^^^^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^
                    //Pass the type as a template parameter            And the value as a constructor parameter


static void TestTaskFunc()
{
    volatile uint32_t test = 0;
}

现场演示


2
投票

的模板类型 CFreeRTOS_Task 是一个指向可调用的指针。只提供 TestTaskFunc 将不会推导出类型(即指向函数的指针),相反,你需要用 decltype 它。

static CFreeRTOS_Task<decltype(TestTaskFunc), 10> testTask("test_task");
//                    ^^^^^^^^
© www.soinside.com 2019 - 2024. All rights reserved.