./1
- Posté le 08/01/2011 à 11:23 Membre depuis le 18/06/2001, 30172 messages
Ca me fait rager, j'ai un programme quasi fini (Par en l'occurence), qui ne l'est pas depuis deux mois car je n'arrive pas à merdouiller un détail à propos de pointeurs de fonctions. Je sais que je dois passer par le typedef kivabien, mais je n'arrive pas à trouver la combinaison gagnante...

La fonction à appeler :
short Callback (void* Data, short Msg)
{
return 0;
}

Et dans main :
typedef short (*Callback) (void*, short);

Foo (Callback); // fail
Foo ((*Callback)); //fail
... // Will always fail, u loose

Les erreurs sonr diverses et variées, ça peut être des "expected expressions before callback", des "callback already defined in another place" toussa

C'est con quand même, mis à part ça mon programme est fini partout ailleurs triso
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./2
- Posté le 08/01/2011 à 11:25 Membre depuis le 11/07/2003, 49343 messages
typedef (short (*) (void*, short)) mon_type; ?
avatar <<< Kernel Extremist©®™ >>>
Aviations Militaires
<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appetissant
./3
- Posté le 08/01/2011 à 11:46 Membre depuis le 18/06/2001, 30172 messages
main.c:41: error: expected identifier or '(' before ')' token

M'enfin Flanker, m'enfin, ça doit être beau en TD embarrassed

(bon ceci dit j'ai pas encore eu le temps de lire le tuto de 0² grin)
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./4
- Posté le 08/01/2011 à 12:05 Membre depuis le 11/06/2001, 19244 messages
Je comprends pas trop ton problème. Est-ce que cet exemple t'aide ?

typedef short (*callback_t)(void *, short);

short Callback (void* Data, short Msg)
{
return 0;
}

short f(callback_t func, void* v, short s)
{
callback_t func2 = func;
return (*func2) (v, s);
}

short g(void *v, short s)
{
return f(Callback, v, s);
}

./5
- Posté le 08/01/2011 à 14:32 Membre depuis le 18/06/2001, 30172 messages
PpHd (./4) :
Est-ce que cet exemple t'aide ?

GRAAAAAAAAAAAAVE !!!!!!!!!!!! Ca compile now !!! Merci !love

Donc je récapitule :
// pdtlib.h

typedef short (*callback_t) (void*, short);
typedef short (*noSwitchFunc_t) (void*);
typedef short (*switchFunc_t) (void*, char);

short pdtlib_ManageCmdline (CMDLINE* CmdLine, void* Data, const char* SwitchList,
callback_t Callback,
noSwitchFunc_t NoSwitchFunc,
switchFunc_t SwitchFunc,
...) __attribute__((stkparm));;


Et dans mon source :
#include "pdtlib.h"

short Callback (void* Data, short Msg)
{
return 0;
}



short NoSwitchFunc (void* Data)
{
return 0;
}



short SwitchArchive (void* Data, char Sign)
{
return 0;
}



int main (int argc, const char** argv)
{
DATA Data;

callback_t Func1 = Callback;
noSwitchFunc_t Func2 = NoSwitchFunc;
switchFunc_t Func3 = SwitchArchive;

pdtlib_InitCmdline(&Data.CmdLine, argc, argv);
pdtlib_ManageCmdline(&Data.CmdLine, &Data, SwitchList, Func1, Func2, Func3);

return 0;
}

Alors, voyez-vous quelque chose qui déconne ? Quelque chose de pas logique ?

(sachant qu'à la différence de ton exemple, ma fonction f est une fonction de dll, donc je ne l'ai pas postée ici.)
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./6
- Posté le 08/01/2011 à 15:45 Membre depuis le 11/06/2001, 19244 messages
Folco (./5) :

Alors, voyez-vous quelque chose qui déconne ? Quelque chose de pas logique ?


Non.
./7
- Posté le 08/01/2011 à 23:33 Membre depuis le 18/06/2001, 30172 messages
Bon, comme je suis un chieur, j'ai essayé un truc : virer les affectation, et passer directement les noms de fonction à ManageCmdline. Résultat, ça compile aussi bien. :
int main (int argc, const char** argv) 
{
DATA Data;

// callback_t Func1 = Callback;
// noSwitchFunc_t Func2 = NoSwitchFunc;
// switchFunc_t Func3 = SwitchArchive;

pdtlib_InitCmdline(&Data.CmdLine, argc, argv);
// pdtlib_ManageCmdline(&Data.CmdLine, &Data, SwitchList, Func1, Func2, Func3);
pdtlib_ManageCmdline(&Data.CmdLine, &Data, SwitchList, Callback, NoSwitchFunc, SwitchArchive);
return 0;
}

C'est normal docteur ?
En tout cas, moi ça m'arrange, je trouve ça tellement plus clair et intuitif !
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./8
- Posté le 08/01/2011 à 23:49 Membre depuis le 15/06/2003, 7959 messages
Oui c'est normal, et heureusement que ça fonctionne ! cheeky
Je ne sais pas si c'est plus clair pour tout le monde (pour moi oui), mais en tout cas ça fait plus propre. ^^
avatar Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
./9
- Posté le 08/01/2011 à 23:52 Membre depuis le 18/06/2001, 30172 messages
Bon ben parfait, je comprends mieux, ça me rassure, merci bien grin
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 16/04/2011 à 21:47 Membre depuis le 18/06/2001, 30172 messages
Bon, je suis encore en train de me faire suer avec la manière de m'exprimer en C. Au lieu de coder un truc intéressant, je viens de passer 1h30 dans des bouquins et trois lignes de merde.

Mon but : écrire une structure contenant un pointeur de fonction utilisant en paramètre un pointeur vers une structure de même type.

Voici ce que j'ai écrit, et qui évidemment ne marche pas (il lui faudrait un ')' juste après l'étoile du pointeur de fonction d'après lui) :

typedef struct DATA;               // Ca c'est pour utiliser dans la structure, qu'il sache à quoi s'en tenir

struct
{
void (*Fonction) (DATA* Data);
} DATA;

Mais ça veut pas. J'ai fouillé mon bouquin et essayé tout un tas de variantes. Je n'ai visiblement pas trouvé la combinaison gagnante pour y arriver. Je ne sais pas si ça pèche à cause du pointeur de fonction, ou du pointeur de structure utilisé dans la déclaration de la structure.

Toujours est-il que ça me pompe puissamment de me taper toujours les mêmes galères en C alors que je suis censé gagner du temps sorry
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 16/04/2011 à 21:58 Membre depuis le 15/06/2003, 7959 messages
Le nom du struct vient après le mot-clé struct. Si tu omets le nom, cela crée une structure anonyme.
->
Dans ton code là, tu crées une variable globale nommée « DATA », et de type struct { void (*Fonction) (DATA* Data); }.
En plus de ça, ton typedef est incorrect. (Le compilateur ne t'as pas balancé une erreur là dessus ?)

Donc voilà, ça ne fonctionne pas, mais c'est normal. tongue

Au minimum, tu devrais avoir ça
struct DATA
{
    void (*Fonction) (struct DATA* Data);
};
Je te laisse mettre les typedefs comme il faur pour faire « joli ». cheeky
avatar Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
- Posté le 16/04/2011 à 22:01 Membre depuis le 16/06/2003, 24345 messages
euh, il faut pas un deuxième argument à ton typedef ? il crie pas quand tu lui dis juste "typedef struct DATA" ??
(cross, oui en plus le nom de la structure n'est pas au bon endroit dans sa déclaration en effet ^^)
avatar « Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Forum Cultures du mondeforum littéraire
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``[u]·[/u] powaaaaaaaaa ! #love#
- Posté le 16/04/2011 à 22:08 Membre depuis le 18/06/2001, 30172 messages
Purée je m'en sortirai jamais sick Je pioche dans du code à moi, dans des exemples, j'ai l'impression que je fais une joyeuse salade de tout ça... Merci beaucoup, je continue.
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 16/04/2011 à 22:23 Membre depuis le 16/06/2001, 59980 messages
protip: typedef n'est qu'un truc qui crée des alias de types, on peut s'en passer.

- Posté le 17/04/2011 à 10:00 Membre depuis le 18/06/2001, 30172 messages
Ah, ça y est, j'ai identifié précisément mon erreur. J'avais écrit ça au début, qui était presque bon :
typedef struct DATA
{
unsigned int CurrentTask;
unsigned int NewTask;
void (*Manage) (DATA* Data);
void (*Display) (DATA* Data);
void (*Destructor) (DATA* Data);
} DATA;

Mais c'était oublier que DATA n'étant pas encore typedefé, je devais mettre "struct DATA" dans les paramètres des fonctions... Quelle bêtise... Merci encore. smile
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 17/04/2011 à 10:59 Membre depuis le 16/06/2001, 59980 messages
vala smile T'as découvert un bon truc formateur pour la suite grin
- Posté le 17/04/2011 à 10:59 Membre depuis le 28/10/2001, 7573 messages
Pourtant, les auto-références sont permises dans des structs, sinon il serait impossible de faire, par exemple,
typedef struct WindowStruct { ... struct WindowStruct *Next; ... } WINDOW;

Et si tu faisais
typedef struct MyDATA { unsigned int CurrentTask; unsigned int NewTask; void (*Manage) (MyDATA *Data); void (*Display) (MyDATA *Data); void (*Destructor) (MyDATA *Data);} DATA

?
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
- Posté le 17/04/2011 à 11:01 Membre depuis le 16/06/2003, 24345 messages
oui l'idéal c'est de mettre le typedef avant plutôt que de tout faire en même temps, à cause de ça (je sais pas pourquoi on voit partout des exemples où le typedef et la définition de la structure sont faits en même temps, pour économiser une ligne de code ?)
typedef struct DATA DATA;

struct DATA
{
unsigned int CurrentTask;
unsigned int NewTask;
void (*Manage) (DATA* Data);
void (*Display) (DATA* Data);
void (*Destructor) (DATA* Data);
};
(double cross)
avatar « Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Forum Cultures du mondeforum littéraire
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``[u]·[/u] powaaaaaaaaa ! #love#
- Posté le 17/04/2011 à 11:09 Membre depuis le 16/06/2003, 24345 messages
Lionel > les auto-références sont permises, mais quand tu écris ce raccourci confusionnant qu'est "typedef struct machin {} bidule;" ça se comporte en fait comme :
struct machin {};
typedef struct machin bidule;

autrement dit la structure est définie dans un premier temps et le typedef n'est fait qu'après. Si tu veux pouvoir faire des auto-références en utilisant l'alias, il faut définir celui-ci avant (comme dans mon post précédent). Sinon les auto-références ne peuvent être faites qu'en utilisant le nom complet du type, à savoir struct machin, et non pas bidule qui n'est pas encore défini.

Dans ton exemple il faudrait mettre "struct MyDATA" et non juste "MyDATA".
avatar « Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Forum Cultures du mondeforum littéraire
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``[u]·[/u] powaaaaaaaaa ! #love#
- Posté le 17/04/2011 à 11:12 Membre depuis le 16/06/2001, 59980 messages
pas mieux ^^
- Posté le 17/04/2011 à 11:14 Membre depuis le 28/10/2001, 7573 messages
Ah oui, j'ai mal lu l'exemple de WindowStruct / WINDOW que je suis pourtant allé consulter exprès grin
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
- Posté le 17/04/2011 à 15:08 Membre depuis le 18/06/2001, 30172 messages
Ok merci. Sally, je vais adopter ta manière de faire, c'est en effet la plus compréhensible et la moins embrouillante à mes yeux. smile
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.