Plantage sur retour d'un CallBack

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Sylvie
Messages : 13
Inscription : sam. 19/nov./2005 17:27
Localisation : Vosge

Plantage sur retour d'un CallBack

Message par Sylvie »

Bonjours a tous.
Probleme sur les CallBack:

Voici le soucis: quand je fait

Code : Tout sélectionner

Procedure Test(var.l, var2.l)
    ... actions diverses
EndProcedure

CallFunctionFast(@Test(), 0, 0) 
pas de soucis, cela fonctionne,
mais quand je fait ceci:

Code : Tout sélectionner

Procedure Test(var.l, var2.l)
    ... actions diverses
EndProcedure

SetCallBack( @Test() )  ; fonction d'une lib ecrite en C de mémo de la fonction 
...
avec le code C suivant...

Code : Tout sélectionner

int (*Fonct)	(int var1, int var2);
// mémo du callback
void SetCallBack( int (*fC) (int var1, int var2))
{  
    Fonct = fC;
}
// une fonction dans la lib, qui se sert du callback
... if(Fonct)	Fonct(val1 , val2);
J'ai un plantage lors de l'appel de la fonction au sein de mon code C.
Il semble que toutes les instructions contenues dans la fonction de Test() passent
mais cela plante au moment du retour de la fonction.
Quelqu'un possède-t-il une expérience dans ce domaine ?
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

essaye avec ProcedureC à la place de Procedure
(ou ProcedureCDLL à la place de ProcedureDLL)

Dri
Sylvie
Messages : 13
Inscription : sam. 19/nov./2005 17:27
Localisation : Vosge

Message par Sylvie »

J'ai éssayé, mais j'obtiens les meme résultat. A croire que ma routine C ne trouve
pas dans la pile l'ADR de retour suite a l'appel de la fonction PB ...
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Mes connaissances du C sont voisines de 0 :D

Mais peut-être que ta fontion C attend un pointeur et pas une adresse

Code : Tout sélectionner

@Test()
passe une valeur sur la pile qui est l'adresse de la fonction

Peut-être faut-il passer l'adresse d'une variable (locale ou globale) qui elle contient l'adresse de la fonction
KarLKoX
Messages : 1191
Inscription : jeu. 26/févr./2004 15:36
Localisation : France
Contact :

Message par KarLKoX »

Par défaut, les callbacks sont _cdecl donc en théorie, oui, il faut utiliser ProcedureC mais il arrive que ça plante selon le compilateur utilisé.
Pour ma part, je type toujours implicitement mes callbacks/pointeurs sur fonction en _stdcall m'évitant ainsi d'utiliser ProcedureC
Exemple :

Code : Tout sélectionner

typedef void (__stdcall  *OGGSTREAM_DSPCALLBACK)(void* buffer, DWORD size);

struct OGG_CALLBACK
{
	void	(__stdcall *Call)(void);						/* The Pointer To The Callback Receiver */
	UINT	Type;												 /* The Array For The CallBacksID */
};

////////////////////////////////////////////////////////////////////////
// Set The new callback (up to OGG_NUM_MAX_CALLBACKS)
///////////////////////////////////////////////////////////////////////
OGGAPI INT API oggstream_DspCreate(OGGSTREAM_DSPCALLBACK CallBack)
{
	if (tDspCBK.numCallBacks == OGG_NUM_MAX_CALLBACKS)	return -1;
	tDspCBK.CallBack[tDspCBK.numCallBacks].Call = CallBack;
	++tDspCBK.numCallBacks;
	return (tDspCBK.numCallBacks-1);
}

[...]
                // We Call Each Active DSP Effect Here 
		for (i=0; i < OGG_NUM_MAX_DSP_CALLBACKS; i++)
		{
			if ( tDspCBK.CallBack[i].Active )
				tDspCBK.CallBack[i].Call(stream, dataToWrite);
		}
[...]

Code : Tout sélectionner

Procedure DspRotator(*buffer.l, size.l)
   [...]
endprocedure

DSP_RotatorID = OggStreamDspCreate(@DspRotator())
"Qui baise trop bouffe un poil." P. Desproges
Sylvie
Messages : 13
Inscription : sam. 19/nov./2005 17:27
Localisation : Vosge

Message par Sylvie »

Merci pour votre aide, mais pour l'instant, meme avec ta solution KarLKoX, cela
plante toujours autant... :cry:

Mais je vais continuer, je vais bien trouver la solution... :wink:
Sylvie
Messages : 13
Inscription : sam. 19/nov./2005 17:27
Localisation : Vosge

Message par Sylvie »

Je reviens a la charge avec mes histoires de CallBack

En fait, le problème est plus profond que cela.
J'écris une petite lib, avec une fonction genre:

Code : Tout sélectionner

Extern "C" {

_declspec(dllexport) void Action1(Type* valeur)
{
  ....
}

}
En suite, j'importe ma petite lib tranquillement, et dans mon code
PB j'ecris tout naturellement dans le corps principal de mon code:

Code : Tout sélectionner

...
Action1(*pointeur)
...
La, pas de soucis, l'action (donc la fonction C), s'execute sans soucis.
Mais maintenant, quand j'écris:

Code : Tout sélectionner

Procedure Mon_action(*pointeur)  ; procedureC meme combat
	Action1(*pointeur)
EndProcedure
...
...
Mon_action(*pointeur)
...
ça plante a tous les coups, avec message 'Invalid Memory Access', le
debuggueur étant arrété sur l'instruction 'ReturnProcedure'
A savoir, que malgrés tout l'instruction C 'Action1()' c'est executée
apparement sans soucis (pointeur bien transmis, affichage d'une petite
boite de dialogue, etc...)



Ou est l'astuce ??
Sylvie
Messages : 13
Inscription : sam. 19/nov./2005 17:27
Localisation : Vosge

Message par Sylvie »

Je savais bien que je trouverais...
Je dois remplacer ce code:

Code : Tout sélectionner

Extern "C" {

_declspec(dllexport) void Action1(Type* valeur)
{
  ....
}

} 
par...

Code : Tout sélectionner

Extern "C" {

_declspec(dllexport) void __stdcall Action1(Type* valeur)
{
  ....
}

} 
Je ne suis qu'une boulet (ou boulettte, boulet n'a pas de féminin.. )
KarLKoX
Messages : 1191
Inscription : jeu. 26/févr./2004 15:36
Localisation : France
Contact :

Message par KarLKoX »

J'ai apparamment oublié dans le code du dessus la définition des macros OGGAPI et API :

Code : Tout sélectionner

#if defined WIN32 && defined _DLL && !defined _LIB
	#ifdef DLL_EXPORTS
		#define OGGAPI __declspec(dllexport)
	#else
		#define OGGAPI __declspec(dllimport)
	#endif
	#ifdef _STDCALL
		#define API __stdcall
	#else
		#define API __cdecl
	#endif
#else
	#define API __stdcall
	#define OGGAPI
#endif
ce qui donnais :

Code : Tout sélectionner

OGGAPI INT API oggstream_DspCreate(OGGSTREAM_DSPCALLBACK CallBack) 
ou :

Code : Tout sélectionner

__declspec(dllexport) INT __stdcall oggstream_DspCreate(OGGSTREAM_DSPCALLBACK CallBack) 
Image
"Qui baise trop bouffe un poil." P. Desproges
Sylvie
Messages : 13
Inscription : sam. 19/nov./2005 17:27
Localisation : Vosge

Message par Sylvie »

Pas de soucis, cela m'a fait chercher, cela ne m'a pas fait de mal,
et comme je ne suis pas resté bloquée 5 jours dessus, no problèmo...
:wink:
Répondre