Page 1 sur 1

Une petite question au sujet de TailBite...

Publié : dim. 15/août/2010 19:19
par El Papounet
Hello,

Voilà, je suis tombé sur un OS et je n'arrive à trouver aucune explication du pourquoi !
Je créer une simple fonction ayant 1 argument string, celle-ci doit me retourner une valeur string.
Pour une certaine souplesse, je suis amené à passer cet argument en concaténant 2 chaines de caractères.

Pour exemple:

Code : Tout sélectionner

ProcedureDLL.s Test(Argument.s)
	
	ProcedureReturn "Resultat"
	
EndProcedure
Si je passe ce simple code à la moulinette avec TailBite pour en faire une librairie utilisateur, et que j'essaie ensuite d'utiliser cette fonction de la manière suivante:

Code : Tout sélectionner

Argument1.s = "Argument 1"
Argument2.s = "Argument 2"
Debug Test(Argument1 + Argument2)
Je m'attends à avoir en retour "Resulat", et bien non ! J'obtiens "Argument 1Argument 2Resultat" :?:
D'où mon interrogation: pourquoi ceci fonctionne très bien si cette fonction est intégrée au programme, alors que le résultat est erroné si elle intégrée à une librairie utilisateur ?

D'avance merci pour vos explications

D

Re: Une petite question au sujet de TailBite...

Publié : lun. 16/août/2010 2:37
par Warkering
Quel est le code de la fonction? Du moins, la partie sur Resultat et les paramètres?

Re: Une petite question au sujet de TailBite...

Publié : lun. 16/août/2010 8:46
par gnozal
Selon les versions de Tailbite et PB, il y a des limitations pour les chaînes de caractères.
Je conseille de ne jamais retourner de litéral mais une variable.

Code : Tout sélectionner

ProcedureDLL.s Test(Argument.s)
   Protected Retour.s
   Retour = "Resultat"
   ; ...
   ProcedureReturn Retour
EndProcedure
De plus, à partir de PB4.20, il ne faut pas utiliser des fonctions qui exportent une chaîne dans la librairie même.
Au lieu de

Code : Tout sélectionner

ProcedureDLL$ proc(a) 
   ProcedureReturn Str(a) 
EndProcedure 

ProcedureDLL$ p(b) 
   ProcedureReturn proc(b) 
EndProcedure
il faut utiliser

Code : Tout sélectionner

Procedure$ proc_private(a) ; fonction privée 
  ProcedureReturn Str(a) 
EndProcedure 
ProcedureDLL$ proc(a) ; fonction exportée (publique)
  ProcedureReturn proc_private(a) 
EndProcedure 
; 
ProcedureDLL$ p(b) 
  ProcedureReturn proc_private(b) ; utilisation de la fonction privée dans la librairie
EndProcedure

Re: Une petite question au sujet de TailBite...

Publié : lun. 16/août/2010 16:41
par El Papounet
Merci pour vos réponses mais j'ai beau retourner le problème dans tous les sens, à chaque fois que je passe un paramètre à ma fonction en concaténant deux chaines, le retour est erroné.

Pour info voilà ce que j'essayais de faire:

Code : Tout sélectionner

Procedure Local_ExtractRootKey(KeyPath.s)

	Select UCase(Left(KeyPath, FindString(KeyPath, "\", 1) - 1))
		Case "HKEY_CLASSES_ROOT", "HKCR"
			ProcedureReturn #HKEY_CLASSES_ROOT
		Case "HKEY_CURRENT_USER", "HKCU"
			ProcedureReturn #HKEY_CURRENT_USER
		Case "HKEY_LOCAL_MACHINE", "HKLM"
			ProcedureReturn #HKEY_LOCAL_MACHINE
		Case "HKEY_USERS", "HKU"
			ProcedureReturn #HKEY_USERS
		Case "HKEY_CURRENT_CONFIG ", "HKCC"
			ProcedureReturn #HKEY_CURRENT_CONFIG
		Default
			ProcedureReturn #NUL
	EndSelect

EndProcedure

Procedure.s Local_ExtractSubKey(KeyPath.s)

	Protected Separator

	If Right(KeyPath, 1) = "\"
		KeyPath = Left(KeyPath, Len(KeyPath) - 1)
	EndIf
	Separator = FindString(KeyPath, "\", 1)
	If Separator
		ProcedureReturn Mid(KeyPath, FindString(KeyPath, "\", 1) + 1)
	Else
		ProcedureReturn ""
	EndIf

EndProcedure

ProcedureDLL.s Reg_GetValue(KeyPath.s, ValueName.s)

	Protected KeyRoot, SubKey.s, hKey, Value.s, i, Type
	Protected lpcbData, *lpData, *Buffer, ptr_lpData, ptr_Buffer

	KeyRoot = Local_ExtractRootKey(KeyPath)
	SubKey  = Local_ExtractSubKey(KeyPath)

	If KeyRoot And SubKey
		If RegOpenKeyEx_(KeyRoot, @SubKey, #NUL, #KEY_READ, @hKey) = #ERROR_SUCCESS
			RegQueryValueEx_(hKey, @ValueName, #NUL, @Type, *lpData, @lpcbData)
			If lpcbData
				*lpData = AllocateMemory(lpcbData)
				If RegQueryValueEx_(hKey, @ValueName, #NUL, @Type, *lpData, @lpcbData) = #ERROR_SUCCESS
					If ValueName
						ValueName = ReplaceString(ValueName, "\", "\\")
						ValueName = ReplaceString(ValueName, #DQUOTE$, "\" + #DQUOTE$)
						
					EndIf
					Select Type
						Case #REG_SZ, #REG_EXPAND_SZ
							Value = PeekS(*lpData)
							Value = ReplaceString(Value, "\\", "\")
							Value = ReplaceString(Value, "\" + Chr(34), Chr(34))			

						Case #REG_DWORD
							Value = LCase(RSet(Hex(PeekL(*lpData), #PB_Integer), 8, "0"))
							
						Case #REG_MULTI_SZ
							*Buffer = AllocateMemory(lpcbData)
							ptr_lpData = *lpData
							ptr_Buffer = *Buffer
							While ptr_lpData < *lpData + lpcbData - SizeOf(Character) * 2
								Value = PeekS(ptr_lpData)
								PokeS(ptr_Buffer, Value)
								ptr_lpData = ptr_lpData + StringByteLength(Value) + SizeOf(Character)
								ptr_Buffer = ptr_Buffer + StringByteLength(Value)
								PokeS(ptr_Buffer, #LF$)
								ptr_Buffer = ptr_Buffer + SizeOf(Character)
								
							Wend
							Value = PeekS(*Buffer)
							FreeMemory(*Buffer)
							
						Default
							*Buffer = AllocateMemory((lpcbData + 1) * 3 * SizeOf(Character))
							ptr_lpData = *lpData
							For i = 0 To lpcbData - 1
								PokeS(*Buffer + i * 3 * SizeOf(Character), LCase(RSet(Hex(PeekB(*lpData + i) & $FF), 2, "0")) + ",")
								
							Next
							PokeS((*Buffer + i * 3 * SizeOf(Character)) - SizeOf(Character), Chr(0))
							Value = PeekS(*Buffer)
							FreeMemory(*Buffer)
							
					EndSelect
					
				EndIf
				FreeMemory(*lpData)
				
			EndIf	
			
		EndIf
		RegCloseKey_(hKey)
		
	EndIf
	
	ProcedureReturn Value
	
EndProcedure
En faisant

Code : Tout sélectionner

Key.s = "HKEY_CLASSES_ROOT\"
SubKey.s = ".exe"
ValueName.s = ""
Value.s = Reg_GetValue(Key + SubKey , ValueName)
Debug Value
En retour j'obtiens HKEY_CLASSES_ROOT\.exeexefile

Par contre

Code : Tout sélectionner

Key.s = "HKEY_CLASSES_ROOT\.exe"
ValueName.s = ""
Value.s = Reg_GetValue(Key, ValueName)
Debug Value
En retour j'ai bien exefile

Re: Une petite question au sujet de TailBite...

Publié : mar. 17/août/2010 8:30
par gnozal
C'est probablement la concaténation dans l'appel à la fonction Reg_GetValue()
Essaie

Code : Tout sélectionner

a$ = Key + SubKey
Value.s = Reg_GetValue(a$ , ValueName)

Re: Une petite question au sujet de TailBite...

Publié : mar. 17/août/2010 9:52
par El Papounet
gnozal a écrit :C'est probablement la concaténation dans l'appel à la fonction Reg_GetValue()
Essaie

Code : Tout sélectionner

a$ = Key + SubKey
Value.s = Reg_GetValue(a$ , ValueName)
Merci pour ton aide

C'était bien ce que j'essayais d'expliquer.
Je voulais simplement savoir s'il y avait un moyen de contourner le problème, car je n'ai pas toujours le réflexe de concaténer l'argument avant l'appel de la fonction.

Re: Une petite question au sujet de TailBite...

Publié : mar. 17/août/2010 12:05
par Ar-S
c'est vrai que c'est étrange comme réaction.

Re: Une petite question au sujet de TailBite...

Publié : mar. 17/août/2010 12:21
par Backup
pas tant que ça

taillbite est un prg qui n'évalue peut etre pas les surcharges dans les paramètres de fonctions

il s'attend a des parametres séparé par des virgules

j'ai pas testé , mais je suppose qu'on ne peut pas inclure non plus,une formule mathématique en dur, en guise de paramètre....

genre

toto(a+b*sin(r),c,d)

quoiqu'il en soit les Strings sont gérées de façon un peut spécial en Purebasic
la preuve, il faut un paramètre particulier si on l'emploi avec les threads....
la gestion par purebasic des Chaine$ a toujours ete sensible