2010-12-14 56 views
-1

Commençons à travailler sur un projet c. Besoin d'aide pour passer des pointeurs de fonction/fonctions macro/etc. Je suis un php & python OO guy, mais nouveau à c. J'ai essayé de généraliser l'exemple pour ce post. J'ai un main.c avec un lib pour le microcontrôleur d'Axon que je travaille avec. Fonctionne comme un charme avec tout dans main.c. J'ai besoin de déplacer certaines fonctionnalités de la main vers des fichiers lib plus organisés au fur et à mesure que mon code grandit. Le microcontrôleur de base lib crée une fonction macro qui me permet d'envoyer des données au microcontrôleur pour faire un mouvement d'asservissement à gauche ou à droite. J'ai maintenant besoin de créer un fichier spécifique au servo (HS-422.c) qui me permettra de passer des références/pointeurs (?) À une fonction générique qui sera exécutée pour chaque servo pour faciliter la duplication du code. N'oubliez pas que je me concentre uniquement sur le passage de macros/fonctions/références de variables à d'autres fonctions et que je les appelle/set. Les autres bases de c je comprends. J'ai dû essayer 100 façons différentes de faire ce travail aujourd'hui sans aucune chance. Donc, juste écrit une version simplifiée en espérant que vous pourriez avoir une idée de ce que je tente.Passage de pointeurs de fonction et de références int à une autre fonction

Nous vous remercions de votre aide!

/* 
* main.h 
* I'm trying to make a pointer or reference to the macro. 
* The original file had: 
* #define servo1(position) servo(PORTE,2,position); 
*/ 

// servo is a macro defined in another microcontroller file 
#define (void)(*servo1)(position) servo(PORTE,2,position); 
#define (void)(*servo2)(position) servo(PORTE,3,position); 


/* main.c */ 

// init main functions 
void servo_scan(void); 

// init vars 
int servo1_location = 0; 
int servo2_location = 0; 

int main(void) 
{ 
    for(;;) 
    { 
    servo_turn(); 
    } 
} 

// get the servos to turn 
void servo_turn(void) 
{ 
    turn_servo(*servo1, &servo1_location, 200); 
    turn_servo(*servo2, &servo2_location, 950); 
} 


/* HS-422.c */ 
void turn_servo(void (*servo)(int position), int &currentLocation, int newLocation) 
{ 
    // turning 
    for(uint16_t i=&currentLocation; i<newLocation; i=i+10) 
    { 
    // turn servo 
    // hoping the specifc passed servo# pointer gets called 
    *servo(i);  

    // set value by reference to origional servo#_location var. making sure. 
    &currentLocation = i; 

    // pause 
    delay_ms(20); 
    } 
} 
+2

Ces # définir sont très sommaires! – leppie

+1

C n'a pas de concept de "références". La seule alternative au passage par valeur est de passer un pointeur. –

+0

Le #define était seulement un exemple .. Je sais que cela ne fonctionne pas. Espérant trouver la bonne façon de le faire. Et désolé je suppose que je voulais clair sur les références. Celles-ci étaient destinées aux variables, donc je pouvais définir les valeurs de servo # _location dans la fonction appelée turn_servo. – pringlized

Répondre

1

J'ai choisi le point principal de votre code et j'ai ce code ci-dessous.
Vous pouvez modifier votre #define dans votre code original.
S'il vous plaît voir le code ci-dessous: (vous pouvez également exécuter cette)

void myFunc(int pos); 
void myFunc2(int pos); 

int main (int argc, const char * argv[]) { 


    typedef void (*pFunc)(int); 
    pFunc pfArr[2]; 
    pfArr[0] = &myFunc; 
    pfArr[1] = &myFunc2; 


    int x = 3; 
    int newLoc = 4; 
    turn_servo(pfArr[1], x, newLoc); 
    turn_servo(pfArr[0], x, newLoc); 


    return 0; 
} 



void turn_servo(void (*servo)(int position), int currentLocation, int newLocation) 
{ 
    printf("\nturn_servo starts"); 
    printf("\nturn_servo currentLocation: %d", currentLocation); 
    printf("\nturn_servo newLocation: %d", newLocation); 
    servo(1); 

} 

void myFunc(int pos) 
{ 
    printf("\nmyFunc starts"); 
    printf("\nmyFunc pos: %d", pos); 
} 

void myFunc2(int pos) 
{ 
    printf("\nmyFunc2 starts"); 
    printf("\nmyFunc2 pos: %d", pos); 
} 

Votre fonction turn_servo() accepte maintenant les deux fonctions en tant que paramètre (soit myFunc() ou ma_fonction2()).
Juste obtenir le point principal de ce code et l'appliquer. J'espère que cela aidera.

+0

Les fonctions myFunc() seront similaires à votre servo (PORTE, 2, position); J'espère que cela aidera. –

+0

Génial .. Merci .. Je vais essayer cette première chose le matin. – pringlized

2

Il est pas vraiment clair pour moi exactement ce que vous essayez d'atteindre, mais il est clair que vous ne comprenez pas vraiment le concept de pointeurs/références en C - donc je vais essayer de clarifier et j'espère que cela vous aidera à mettre en œuvre ce dont vous avez besoin. Premièrement, il n'y a pas de "référence" en C. La seule alternative au passage par valeur est de passer un pointeur. Un pointeur est simplement une adresse mémoire, et vous pouvez obtenir un pointeur (adresse mémoire) à une variable en utilisant l'opérateur & (adresse de). Lors du passage d'une variable de pointeur à une fonction, vous faites quelque chose comme ce qui suit:

Etant donnée une fonction qui prend un pointeur:

int foo(int* pointer);

Vous passeriez l'adresse mémoire d'une variable int à cette fonction comme ceci:

int x = 10; 
foo(&x); 

donc dès le départ, vous pouvez voir que votre définition de la fonction ci-dessus est erroné:

void turn_servo(void (*servo)(int position), int &currentLocation, int newLocation); 

Ceci est simplement une erreur de syntaxe. Il ne compilera pas à cause de int &currentLocation. L'opérateur & est utilisé pour prendre l'adresse d'une variable. Il ne peut pas être utilisé dans un paramètre de fonction. Si vous voulez une « référence » à currentLocation, vous devez passer un pointeur, de sorte que vos paramètres de fonction doit être écrit:

void turn_servo(void (*servo)(int position), int* currentLocation, int newLocation); 

En second lieu, lorsque vous souhaitez modifier la valeur pointée par le pointeur currentLocation, vous devez utiliser l'opérateur * pour déréférencer le pointeur. Ainsi, la ligne où vous définissez currentLocation n'est pas correcte.Ce que vous voulez dire est:

// set value by to origional servo#_location var. making sure. 
*currentLocation = i; 

Et bien sûr, la ligne:

for(uint16_t i=&currentLocation; i<newLocation; i=i+10) 

devrait être:

for(uint16_t i= *currentLocation; i<newLocation; i=i+10) 

Notez que dans votre code d'origine que vous utilisez l'opérateur & dans les deux cas, qui prend l'adresse d'une variable. Puisque currentLocation est déjà une adresse de mémoire, cela conduirait à prendre l'adresse d'une adresse, également connue sous le nom de pointeur-vers-un-pointeur, ce qui n'est certainement pas ce que vous voulez ici. Enfin, l'expression "pointeur ou référence à la macro" est complètement absurde. Une macro est pas une fonction. Cela ressemble plus à une méta-fonction: il s'agit essentiellement d'un modèle utilisé par le C preprocessor pour générer du code source supplémentaire. Le préprocesseur C est appelé avant la phase de compilation et agit essentiellement comme un mécanisme de recherche/remplacement dans le code source. Vous ne pouvez pas avoir un pointeur à une macro, car à toutes fins utiles, les macros n'existent même pas dans la phase de compilation. Ils ne sont significatifs que pour le préprocesseur. Il peut y avoir plus ici, mais finalement vous semblez avoir une incompréhension fondamentale des pointeurs (ainsi que des macros) en C, et à moins de fournir un tutoriel complet, le mieux que je peux faire est de signaler les problèmes de syntaxe. Je vous recommande fortement de lire un good introductory book to C, qui ira certainement sur les pointeurs, les macros et les fonctions.

+0

Merci d'avoir pris le temps. Profondément apprécié. Lire une variété de sources aujourd'hui sur les pointeurs. Beaucoup à saisir encore. Expérimenté dans de petits exemples et ils ont bien fonctionné dans un seul fichier. Essayer trop de résoudre trop à la fois. Pour extrapoler plus loin mon plus gros problème était de prendre la macro servo() avec laquelle je travaille avec main.h et d'essayer d'obtenir un pointeur. Je sais maintenant que ce n'est pas possible. servo() est une macro à une macro. Pensez que j'ai besoin de creuser dans le noyau lib, de refactoriser ces macros jusqu'à leur racine et de réécrire un pointeur de base solide. Merci! – pringlized