2017-03-27 10 views
3

私はCを学ぼうとしていますが、私はこの問題に悩まされています。私はこの構造体でリンクされたリストを作成したいと思います。私は異なるled_blinking関数を含む異なる種類のデータでリストを作成しようとしています。問題は、関数ポインタをリスト内の構造体に追加して関数を呼び出すことができないことです。誰かがこの問題で私を助けることができますか?私は間違って何をしていますか?structからfunctionpointerで関数を呼び出す方法は?

#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 
#include <stdbool.h> 
#include <tm4c123gh6pm.h> 
#include <sysctl.h> 
#include <gpio.h> 

void ledRedTask(){ 
    GPIO_PORTF_DATA_R = RED; 
    delay(); 
} 

void ledGreenTask(){ 
    GPIO_PORTF_DATA_R = GREEN; 
    delay(); 
} 

void ledBlueTask(){ 
    GPIO_PORTF_DATA_R = BLUE; 
    delay(); 
} 

void ledYellowTask(){ 
    GPIO_PORTF_DATA_R = YELLOW; 
    delay(); 
} 

void ledPinkTask(){ 
    GPIO_PORTF_DATA_R = PINK; 
    delay(); 
} 

void ledAquaTask(){ 
    GPIO_PORTF_DATA_R = AQUA; 
    delay(); 
} 

struct taskStruct{ 
    int taskNumber; 
    int taskTime; 
    void (*functionTask)(void *); 
    struct taskStruct *next; 
}; 

struct taskStruct *head = NULL; 
struct taskStruct *curr = NULL; 

struct taskStruct* create_list(int taskNumber, void(led_task)(), int delay) 
{ 
    struct taskStruct* ptr = (struct taskStruct*)malloc(sizeof(struct               taskStruct)); 
    if(NULL == ptr) 
    { 
     return NULL; 
    } 
    ptr->taskNumber = taskNumber; 
    ptr->taskTime = delay; 
    ptr->functionTask = led_task; 
    ptr->next = NULL; 

    head = curr = ptr; 
    return ptr; 
} 

struct taskStruct* add_to_list(int taskNumber, bool add_to_end, void(ledTask)(), int ticks_delay) 
{ 
    //If list is not created yet, create list 
    if(NULL == head) 
    { 
     return (create_list(taskNumber, ledTask, ticks_delay)); 
    } 

    struct taskStruct *ptr = (struct taskStruct*)malloc(sizeof(struct taskStruct)); 

    ptr->taskNumber = taskNumber; 
    ptr->taskTime = ticks_delay; 
    ptr->functionTask = ledTask; 
    ptr->next = NULL; 

    if(add_to_end) 
    { 
     curr->next = ptr; 
     curr = ptr; 
    } 
    else 
    { 
     ptr->next = head; 
     head = ptr; 
    } 
    return ptr; 
} 

void printTaskList(void) 
{ 
    struct taskStruct *ptr = head; 

    while(ptr != NULL) 
    { 
     ptr = ptr->next; 
    } 
    return; 
} 

struct taskStruct* search_in_list(int taskNumber, struct taskStruct **prev) 
{ 
    struct taskStruct *ptr = head; 
    struct taskStruct *tmp = NULL; 
    bool found = false; 

    while(ptr != NULL) 
    { 
     if(ptr->taskNumber == taskNumber) 
     { 
      found = true; 
      break; 
     } 
     else 
     { 
      tmp = ptr; 
      ptr = ptr->next; 
     } 
    } 

    if(true == found) 
    { 
     if(prev) 
      *prev = tmp; 
     return ptr; 
    } 
    else 
    { 
     return NULL; 
    } 
} 

void main(){ 
    initSystem(); 

    struct taskStruct* ptr = NULL; 

    printTaskList(); 

    //add new tasks with tasknumber, adding to end of list?, which color should be used?, for how long? 
    add_to_list(0, true, ledRedTask, 100); 
    add_to_list(1, true, ledRedTask, 100); 
    add_to_list(2, true, ledRedTask, 100); 
    //add_to_list(2, true, green, 20); 
    //add_to_list(3, true, blue, 5000); 

    printTaskList(); 

    while(1){ 

     ptr = search_in_list(1, NULL); 


     __asm(" WFI"); 
    } 
} 

このコードは、Tiva TI Lauchpad用に開発されたものです。助けてください。

+0

注:組み込みプログラミングで**変数**の関数ポインタを使用することは、正当な理由で多くのコーディング標準では許可されていません。動的メモリ割り当てと同じです。組み込みプログラミングは、PCプログラミングとはまったく異なります。 'malloc'と' friend'や 'void *'の結果をキャストすることは、常に悪い考えです。 – Olaf

答えて

2

への関数ポインタの宣言が、割り当てられる関数のプロトタイプと一致する必要があります。この問題は、次のような変更によって処理できます。

は、このようなあなたの関数のプロトタイプを変更

void ledRedTask(void) { ... } 

void ledGreenTask(void) { ... } 

etc... 

は、その後、あなたがそれらの機能のプロトタイプ 試合への道であなたの関数ポインタを宣言します。

void (*functionTask)(void); // <-- NOT void (*functionTask)(void *); 

あなたはポインタを設定することができ、すなわち

ptr->functionTask = ledTask; 

そして、

ptr->functionTask(); 
+0

'funcname(void *)'は、パラメータが期待されない 'funcname(void)'ではなく、voidポインタのパラメータを期待しているという明白な違いを述べてください。 – alvits

+1

ありがとう!!それは、必要なものだけで動作します。 – RoboRichio

関連する問題