1

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

2

typedef (short (*) (void*, short)) mon_type; ?
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<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 appétissant

3

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)

4

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

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.)

6

Folco (./5) :
Alors, voyez-vous quelque chose qui déconne ? Quelque chose de pas logique ?


Non.

7

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 !

8

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

Bon ben parfait, je comprends mieux, ça me rassure, merci bien grin

10

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

11

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
ction) (struct DATA* Data); };Au minimum, tu devrais avoir çastruct DATA { void (*FonJe 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

12

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.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

13

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.

14

protip: typedef n'est qu'un truc qui crée des alias de types, on peut s'en passer.

15

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

16

vala smile T'as découvert un bon truc formateur pour la suite grin

17

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.

18

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.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

19

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.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

20

21

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.

22

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