1

Bon j'ai un algo codé en C qui a besoin d'un callback pour faire ses printf
[nosmile]
j'aimerais bien lui filer une méthode C++

Là je me fais insulter par le compilo:

ne 23
code:typedef int (*debug_f)(char *,...);
...
sim=new SimulationModel((debug_f)debugCallback);//lig

ça m'a dit:
dlgsim.cpp:23:error: argument of type `int (DlgSim::)(char*, ...)' does not match `int (*)(char*, ...)'
hum
Bon je mets une vraie adresse:
ack);code:sim=new SimulationModel((debug_f)&debugCallb
llback'
et paf:dlgsim.cpp:23:error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.\
Say `&DlgSim::debugCa

je fais ce qu'il dit:
ack);code:sim=new SimulationModel((debug_f)&DlgSim::debugCallb
et là c'est le drame:
dlgsim.cpp:23:error: converting from `int (DlgSim::*)(char*, ...)' to `int (*)(char*, ...)'

bon, après réflexion, je veux bien qu'il veuille pas exécuter le truc, vu qu'il connaitra pas this.

Alors je fais comment? Un membre statique, une variable de Classe qui contiendra un pointeur vers l'instance que je voulais appeler?

mais c'est horriblement dégeu!

snif sad

2

Effectivement tu ne peux pas appeler ta méthode, puisqu'il te manque l'instance de classe. Il y a surement des bidouillages bien crades à base de casts pour que ça marche (l'instance qui appelle une méthode n'est que son 1er paramètre après tout), mais sinon dans ton cas il semblerait plus logique de faire une méthode statique, c'est à dire une méthode qui s'appelle à partir de la classe et non d'un objet (mais qui du coup ne peut pas faire référence à "this").
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

3

mouais je trifouillerai les casts plus tard. Ca marchera si je me démerde pour ajouter un arg de type pointeur vers ma classe devant tous les autres?

bon maintenant j'ai ça:
(même fonction)...
	DlgSim::staticInstance=this;
	sim=new SimulationModel((debug_f)staticDebugCallback);
}

int DlgSim::staticDebugCallback(char *fmt, ...)
{
	va_list ap;
	va_start(ap,fmt);
	int val=staticInstance->debugCallback(fmt,ap);
	va_end(ap);
	return val;
}


et j'ai ajouté les déclarations quifo dans la classe:
public:
	int debugCallback(char *fmt, va_list ap);
	static int staticDebugCallback(char *fmt, ...);
private:
	static DlgSim *staticInstance;

et là il me chie:
dlgsim.cpp:23:undefined reference to `DlgSim::staticInstance'
c'est l'affectation qui foire, et je pige pas pourquoi il trouve pas ce bidulesorry


edit: âââh faut le déclarer a l'extérieur: celui qui m'explique pourquoi a droit a un carambar:
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/cplr038.htm

4

export "C" { ... } ? (pas sûr de la syntaxe, à vérifier sur google)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

5

nan nan le champ statique de la classe est automatiquement déclaré extern triso donc quelque part dans un .cpp il faut le déclarer:

class_x.h

class X
{
public:
      static int i;
};


class_x.cpp
int X::i = 0; // definition outside class declaration

6

extern et export "C" n'ont pas grand chose à voir, je ne sais pas comment est structuré ton code mais tu pourrais en avoir besoin.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

7

d'ailleurs c'est extern "C" {...} et je l'ai déja mis là ou il faut, je la connaissais déja cette petite couillonnerie hehe

8

ah c'est extern aussi, au temps pour moi
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

9

les symboles C++ et C ne sont pas les même d'ou le export C.
Quand a ton probleme, ne vaudrait t'il pas mieux inverser la dependance et faire que le c++ depende du C (je dois dire que dans l'autre sens ca me semble un peu couillon lol).

10

non j'ai besoin de callbacks dans le C

cet algo est pour le moment testé en C++ desktop mais il sera embarqué dans un autre endroit.

Bref, j'ai pas le choix de l'archi hehe

11

Tu peux pas exporter en C++ un pointeur de méthode ? Bref créer une sorte de delegate en C++, exportable en C?
avatar
la Nature nous montre seulement la queue du lion. Mais je suis certain que le lion a qui elle appartient pense qu'il ne peut pas se révéler en une fois en raison de son immense taille.

- Fondateur de Ti-Gen -: http://www.tigen.org

- Membre du Groupe Orage Studio -: http://oragestudio.free.fr/

- Mon site perso -: http://tisofts.free.fr

Projets TI68K en cours:
GFA-Basic = http://www.tigen.org/gfabasic
Arkanoid.
PolySnd 3.0.

12

ben une méthode d'instance, tu peux, mais en C tu pourras pas l'utiliser a moins de faire des casts hideux pour envoyer l'argument this en premier avant les autres grin

13

la solution c'est tu fais une inersion de dependance:
Au lieu de dependre directement de ton appelle de fonction, tu depends d'une interface (structure de pointeur en C).
Et tu implementes ton interface pour les différents cas. En c++ tu mets simplement l'appel de fonction C++. ton implementation d'interface est spécifique a ton "usecase" donc tu peux le faire en C++.

14

et je l'ai toujours dans l'os, puisque je peux pas appeler une méthode d'instance en C, vu que j'ai pas de "this" en C triso

15

tu aggreges le this en element "privé" dans l'implementation de ton interface. Je vois pas le problème, et je l'ai déjà fait donc dit moi pas que ca marche pas wink

16

JackosKing> c'est un truc dans ce genre dont tu parles ?
// C++
void *instanceMaClasse(void)
{
    return static_cast<void*>(new MaClasse());
}

void appelMethode(void *instance)
{
    static_cast<MaClasse*>(instance)->Methode();
}

/* C */
void *instance = instanceMaClasse();
appelMethode(instance);


bon je suppose que les casts en void* doivent plus ou moins foirer, mais est ce qu'au moins c'est l'idée ?
avatar

17

c'est syma ce truc

en fait je n'ai *absolument* aucune idée du fonctionnement de static_cast<T>

c'est une bonne occasion pour apprendre.

je sais pas si ça va m'aider.
en gros j'ai un algo en C qui utilise des callbacks.
j'aimerais que ces callbacks pointent vers des méthodes d'instance, mais on peut pas.
en fait, ce que j'ai fait, c'est un champ statique qui contient un pointeur vers une instance de ma classe, et des méthodes statiques qui appellent les méthodes virtuelles de cette instance, ça fait à peu près pareil en fait smile

18

le static_cast c'est à peu près l'équivalent du cast du C. tu ne peux juste pas enlever le caractère const d'une variable, faut utiliser un autre cast pour ça
avatar

19

mais pourquoi en avoir fait un mot clé, ie quelle est la diff entre (Trucmuche)var et static_cast<Trucmuche>var ?

20

Bon aux erreurs de compilation pres (j'ai pas de compilo la... et on est dimanche wink):
interface.h
#ifndef INTERFACE_H
#define INTERFACE_H

struct SInterfaceTable{
// Ici table de pointeur du type de tes fonctions de ton interface;
};

struct SInterface{
 SInterfaceTable *pVTable;
};
typedef struct SInterface Interface;

#endif INTERFACE_H


impl.h
#ifndef IMPL_H
#define IMPL_H

struct Impl;
typedef struct SImpl Impl;

Impl* Impl_Create();

#endif // IMPL_H

impl.c
#include "Impl.h"
#include "Interface.h"

struct Impl{
	Interface super;
};

static const SInterfaceTable * const pVTable = { func1, func2...};

Impl* Impl_Create(){
Impl* pNewInstance = malloc(sizeof(Impl));
pNewInstance.super->pVTable = pVTable;
}

void func1(Interface *_pThis, char *_pProut...){
	Impl pThis= (Impl*)_pThis;
	assert(pThis->pVTable == pVTable);

	// Do whatever you want here
}

main.c

#include "Interface.h"
#include "Impl.h"

void toto(Interface *pInterface){
	pInterface->pVTable.func1(pInterface, "prout" ...);
}

int main(..){
	Impl* pOneImpl = Impl_Create();
	toto((Interface*)pOneImpl);
	
	return 42;
}

21

sûrement parcequ'ils ont introduits d'autres casts (const_cast, dynamic_cast, et reinterpret_cast) donc autant utiliser aussi un mot clé pour le cast classique.

après une petite recherche, il semble que le cast C marche dans tous les cas, alors que les casts C++ correspondent chacun à un aspect du cast C. Donc si tu utilises un cast C++, tu auras une erreur de compilation si tu l'utilises mal, alors qu'avec un cast C mal utilisé tu risques d'avoir un programme qui fait n'importe quoi
avatar

22

attends, avec pVTable , tu me fais du c++ en C, là ,non? #trihum#

23

Tout dépend si ta classe hérite de méthodes virtuelles. Dans ce cas la gestion de la vtable en C est obligatoire.
avatar
la Nature nous montre seulement la queue du lion. Mais je suis certain que le lion a qui elle appartient pense qu'il ne peut pas se révéler en une fois en raison de son immense taille.

- Fondateur de Ti-Gen -: http://www.tigen.org

- Membre du Groupe Orage Studio -: http://oragestudio.free.fr/

- Mon site perso -: http://tisofts.free.fr

Projets TI68K en cours:
GFA-Basic = http://www.tigen.org/gfabasic
Arkanoid.
PolySnd 3.0.

24

J'avoue que je ne comprends pas bien non plus le coup de la VTable...
L'héritage n'est pas géré côté C++ lorsque tu fais ton ((MaClasse*)pointeur_void)->MaFonction(...) ? confus
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

25

GoldenCrystal (./24) :
J'avoue que je ne comprends pas bien non plus le coup de la VTable...
L'héritage n'est pas géré côté C++ lorsque tu fais ton ((MaClasse*)pointeur_void)->MaFonction(...) ? confus


Je ne penses pas d'où l'existence de dynamic_cast ? (à confirmer)
avatar
la Nature nous montre seulement la queue du lion. Mais je suis certain que le lion a qui elle appartient pense qu'il ne peut pas se révéler en une fois en raison de son immense taille.

- Fondateur de Ti-Gen -: http://www.tigen.org

- Membre du Groupe Orage Studio -: http://oragestudio.free.fr/

- Mon site perso -: http://tisofts.free.fr

Projets TI68K en cours:
GFA-Basic = http://www.tigen.org/gfabasic
Arkanoid.
PolySnd 3.0.

26

Heu la c'est pour implementer une interface C wink Donc l'interface doit restée commune au C et l'implémentation vous faites ce que vous voulez

27

geogeo> si si, l'héritage est géré dans tous les cas de cast. Si la méthode est virtuelle, peu importe si tu castes ta variable en son type de base, c'est toujours la méthode du type dérivé quie sera appellé.
La différence avec le static_cast c'est que le dynamic_cast est fait à l'execution et renverra un pointeur NULL si tu tentes de caster une variale vers un type qui n'est pas le sien.
Class Base {};
Class DeriveA : public Base {};
Class DeriveB : public Base {};

Base *classe = new DeriveA;
dynamic_cast<DeriveB*>(classe); // renvoit NULL

avatar

28

bon je m'en suis sorti avec un champ void *priv dans la structure de données associée à l'algo, que je charge avec l'instance de classe qui m'intéresse.

sinon
int SimulationModel::vctlPeriph(int cmd, int value)
{
	switch(cmd) {
...
}
/*static*/ int SimulationModel::sctlPeriph(struct algo_data *data, int cmd, int value) {
	int v=static_cast<SimulationModel*>(data->priv)->vctlPeriph(cmd,value);
...
}

rah ça fait du code ultra geek le c++ trilove

sinon je suppose que static_cast est très con:
template <typename T> T static_cast(void *value) { return (T)value};
ou un truc comme ça, je connais pas la syntaxe

29

squalyl (./28) :
bon je m'en suis sorti avec un champ void *priv dans la structure de données associée à l'algo, que je charge avec l'instance de classe qui m'intéresse.

Effectivement, c'est ça la bonne solution.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

30

Aze: Pourquoi passer par un pointeur générique quand on peut utiliser un pointeur de structure déclarée mais non-définie?
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.