Page 1 sur 1

Simplifier les appels fonction string d'une DLL [Impossible]

Publié : lun. 21/déc./2009 7:41
par Kwai chang caine
Bonjour la famille :D

Apres avoir essayé avec succes mais quand meme pendant un mois et demi, de simplifier le passage d'un tableau de string a une DLL.

KCC se lance dans une nouvelle aventure : La "simplification" des appels de fonctions strings

En effet, l'appel des fonctions, je l'utilisais au plus simple comme ça :

Code : Tout sélectionner

RetourFonction$ = Peeks(CallFunction(0, Fonction, Parametre1,Parametre2)) 
Mais mon bon GNOZAL et je crois mon bon DENIS aussi :roll:, ont ecris que c'est pas bien , car on ne teste pas le retour et que ça peut planter.

Fort de cette remarque, parce que KCC, il cause beaucoup certes, mais il ecoute aussi :D
J'me suis dit, vu que tu apelles toute les trois lignes ta super DLL, ne serait il pas bon de faire une fonction d'appel simplifié, qui comprendrait la sécurité et tout le toutim :roll:

J'avais deja fait un POST de ce genre, mais ça n'avait pas été concluant.
Alors je relance le sujet, car il serait bien de pouvoir faire un appel protégé en une ligne de fonctions.
Et vu que mon FRED d'amour, il m'a pas envoyé de carte d'invitation pour changer les appels de fonctions, et que maintenant il dit que il faut utiliser les PROTOTRUCS, une fonction que j'y comprend rien, ou presque.
Je me suis dit que si je mettais les PROTOTRUCS dans une jolie procedure, et bien j'aurais pas a me casse la tete a essayer de les comprendre, puique je les verrait plus :mrgreen:

Alors ce matin, la tete in the "ionfe", j'ai codé ça.
Mais evidemment les callfunction que j'aime y marchent...et les PROTOZOIDES qui savent que je les aiment pas.......et ben y marchent pas :?

Alors si quinquin, a une meilleur idée, pour creer ce genre d'appel...ou si on peut me dire ou est le "Miasme"...et bien ce serait drolement gentil 8)
J'ai choisi le passage de parametres par les strings et des separateurs, car j'ai pas trouvé mieux pour passer des chiffres et des lettres et ceci sans limite de nombre.
En effet, l'avantage par cette methode c'est que l'on met autant de parametres que l'on veut en les separant d'une barre 8)
La je me suis arretté à 5, mais on peut faire plus evidemment :D

Code de l'exe

Code : Tout sélectionner

Prototype.l Generic(Texte1.s = "", Texte2.s = "", Texte3.s = "", Texte4.s = "", Texte5.s = "")

Procedure.s CallFunctionString(IdDll, Fonction.s, Parametres.s = "")
 
 Protected RetourFonction.l
 
 If Trim(Parametres) = ""
  
  RetourFonction = CallFunction(IdDll, Fonction, @"")
 
 Else 
  
  Select CountString(Parametres, "|")
   Case 0
    RetourFonction = CallFunction(IdDll, Fonction, @Parametres)
   Case 1
    Para1.s = StringField(Parametres, 1, "|")
    Para2.s = StringField(Parametres, 2, "|")
    RetourFonction = CallFunction(IdDll, Fonction, @Para1, @Para2)
   Case 2
    Para1.s = StringField(Parametres, 1, "|")
    Para2.s = StringField(Parametres, 2, "|")
    Para3.s = StringField(Parametres, 3, "|")
    RetourFonction = CallFunction(IdDll, Fonction, @Para1, @Para2, @Para3)
   Case 3
    Para1.s = StringField(Parametres, 1, "|")
    Para2.s = StringField(Parametres, 2, "|")
    Para3.s = StringField(Parametres, 3, "|")
    Para4.s = StringField(Parametres, 4, "|")
    RetourFonction = CallFunction(IdDll, Fonction, @Para1, @Para2, @Para3, @Para4)
   Case 4
    Para1.s = StringField(Parametres, 1, "|")
    Para2.s = StringField(Parametres, 2, "|")
    Para3.s = StringField(Parametres, 3, "|")
    Para4.s = StringField(Parametres, 4, "|")
    Para5.s = StringField(Parametres, 5, "|")
    RetourFonction = CallFunction(IdDll, Fonction, @Para1, @Para2, @Para3, @Para4, @Para5)
   EndSelect 
  
  EndIf  
 
  If RetourFonction
   ProcedureReturn PeekS(RetourFonction)
  EndIf 
 
EndProcedure

Procedure.s CallProtoString(IdDll, Fonction.s, Parametres.s = "")
 
 Protected RetourFonction.l
 
 If Trim(Parametres) = ""
  
  Proto.Generic = GetFunction(0, Fonction)
  RetourFonction = Proto("")
  
 Else 
  
  Select CountString(Parametres, "|")
   Case 0
    Proto.Generic = GetFunction(0, Fonction)
    RetourFonction = Proto(Parametres)
   Case 1
    Para1.s = StringField(Parametres, 1, "|")
    Para2.s = StringField(Parametres, 2, "|")
    Proto.Generic = GetFunction(0, Fonction)
    RetourFonction = Proto(Para1, Para2)
   Case 2
    Para1.s = StringField(Parametres, 1, "|")
    Para2.s = StringField(Parametres, 2, "|")
    Para3.s = StringField(Parametres, 3, "|")
    Proto.Generic = GetFunction(0, Fonction)
    RetourFonction = Proto(Para1, Para2, Para3)
   Case 3
    Para1.s = StringField(Parametres, 1, "|")
    Para2.s = StringField(Parametres, 2, "|")
    Para3.s = StringField(Parametres, 3, "|")
    Para4.s = StringField(Parametres, 4, "|")
    Proto.Generic = GetFunction(0, Fonction)
    RetourFonction = Proto(Para1, Para2, Para3, Para4)
   Case 4
    Para1.s = StringField(Parametres, 1, "|")
    Para2.s = StringField(Parametres, 2, "|")
    Para3.s = StringField(Parametres, 3, "|")
    Para4.s = StringField(Parametres, 4, "|")
    Para5.s = StringField(Parametres, 5, "|")
    Proto.Generic = GetFunction(0, Fonction)
    RetourFonction = Proto(Para1, Para2, Para3, Para4, Para5)
   Default 
    ProcedureReturn 
  EndSelect
   
  If RetourFonction
   ProcedureReturn PeekS(RetourFonction)
  EndIf 
 
 EndIf
 
EndProcedure


OpenLibrary(0, "DllMessageBox.dll")
 
 Debug CallProtoString(0, "MessageBox1")
 Debug CallProtoString(0, "MessageBox1", "Hello 1")
 Debug CallProtoString(0, "MessageBox2", "Hello 1|2")
 Debug CallProtoString(0, "MessageBox2", "Hello 1|2|3")
 Debug CallProtoString(0, "MessageBox2", "Hello 1|2|3|4")
 Debug CallProtoString(0, "MessageBox2", "Hello 1|2|3|4|5")

 Debug CallFunctionString(0, "MessageBox1")
 Debug CallFunctionString(0, "MessageBox1", "Hello 1")
 Debug CallFunctionString(0, "MessageBox2", "Hello 1|2")
 Debug CallFunctionString(0, "MessageBox3", "Hello 1|2|3")
 Debug CallFunctionString(0, "MessageBox4", "Hello 1|2|3|4")
 Debug CallFunctionString(0, "MessageBox5", "Hello 1|2|3|4|5")
 
CloseLibrary(0)
Code de la DLL

Code : Tout sélectionner

ProcedureDLL.s MessageBox1(Texte.s)
 MessageRequester("Message de la Dll 1", Texte)
 ProcedureReturn Texte
EndProcedure

ProcedureDLL.s MessageBox2(Texte1.s, Texte2.s)
 Texte$ = Texte1 + " " + Texte2
 MessageRequester("Message de la Dll 2", Texte$)
 ProcedureReturn Texte$
EndProcedure

ProcedureDLL.s MessageBox3(Texte1.s, Texte2.s, Texte3.s)
 Texte$ = Texte1 + " " + Texte2 + " " + Texte3
 MessageRequester("Message de la Dll 3", Texte$)
 ProcedureReturn Texte$
EndProcedure

ProcedureDLL.s MessageBox4(Texte1.s, Texte2.s, Texte3.s, Texte4.s)
 Texte$ = Texte1 + " " + Texte2 + " " + Texte3 + " " + Texte4
 MessageRequester("Message de la Dll 4", Texte$)
 ProcedureReturn Texte$
EndProcedure

ProcedureDLL.s MessageBox5(Texte1.s, Texte2.s, Texte3.s, Texte4.s, Texte5.s)
 Texte$ = Texte1 + " " + Texte2 + " " + Texte3 + " " + Texte4 + " " + Texte5
 MessageRequester("Message de la Dll 5", Texte$)
 ProcedureReturn Texte$
EndProcedure

Je vous remercie

Re: Simplifier et proteger les appels fonction string à une DLL

Publié : lun. 21/déc./2009 10:49
par cederavic
Je précise dès le départ, je n'ai jamais utilisé les prototype non plus, mais j'ai l'impression que c'est plus pour un problème de confort que de sécurité...
Je sais pas si j'ai bien compris ce que tu voulais faire, mais j'ai quand même essayé quelque chose...

Enfait il faudrait savoir si tu connais à l'avance le nombre de paramètre nécessaire et si tu en aura besoin par la suite. Si c'est le cas, le mieux je pense est de t'utiliser une structure et allouer un pointeur directement depuis la dll qui va te le renvoyer au programme comme ceci :

Programme

Code : Tout sélectionner

Structure MsgBox_Struct
  Parm1.s
  Parm2.l
  Parm3.s
  Parm4.f
  Text.s
EndStructure

Prototype.l MessageBox(Parm1.s = "", Parm2.l = 0, Parm3.s = "", Parm4.f= 0.0)
  
OpenLibrary(0, "DllMessageBox.dll")

  MsgBox.MessageBox = GetFunction(0, "MessageBox")
  *Tmp1 : *Tmp1.MsgBox_Struct = MsgBox("Hello 1")
  If *Tmp1 : Debug *Tmp1\Text : EndIf
  *Tmp2.MsgBox_Struct =  MsgBox("Hello 1", 2)
  If *Tmp1 : Debug *Tmp2\Text : EndIf
  *Tmp3.MsgBox_Struct =  MsgBox("Hello 1", 2, "3")
  If *Tmp1 : Debug *Tmp3\Text : EndIf
  *Tmp4.MsgBox_Struct =  MsgBox("Hello 1", 2, "3", 4.7)
  If *Tmp1 : Debug *Tmp4\Text : EndIf

CloseLibrary(0)
Dll

Code : Tout sélectionner

Structure MsgBox_Struct
  Parm1.s
  Parm2.l
  Parm3.s
  Parm4.f
  Text.s
EndStructure

ProcedureDLL.i MessageBox(Parm1.s = "", Parm2.l = 0, Parm3.s = "", Parm4.f= 0.0)
  *Result.MsgBox_Struct = AllocateMemory(SizeOf(MsgBox_Struct))
  *Result\Parm1 = Parm1 : *Result\Parm2 = Parm2 : *Result\Parm3 = Parm3 : *Result\Parm4 = Parm4
  *Result\Text = *Result\Parm1 + " " + Str(*Result\Parm2) + " " + *Result\Parm3 + " " + StrF(*Result\Parm4)
  MessageRequester("Message de la Dll 1", *Result\Text)
  ProcedureReturn *Result
EndProcedure
Ici on a une structure avec tout les paramètres dont on a besoin + un champs qui va "combiner" le tout (après faut voir ce que tu veux faire exactement). On appel donc la procédure de la dll via le prototype avec plus ou moins de paramètres, celle ci alloue un espace mémoire, y stock les paramètres, les combine dans le champs Text (j'ai mis un espace pour les séparer, mais c'est juste à titre d'exemple), afficher le msgrequester avec le fameux texte et nous renvois le pointeur.
Après avoir vérifier que le pointeur n'est pas null tu peux accéder directement au paramètres (que la fonction de la dll aurait très bien pu modifier) et au "Text".

Je ne suis pas sur que ça puisse t'aider, auquel cas dis nous exactement ce dont tu as besoin (Nombre de paramètres donné? Stockage des paramètres? Retour en String obligatoire? etc...)

Re: Simplifier et proteger les appels fonction string à une DLL

Publié : lun. 21/déc./2009 15:09
par Kwai chang caine
Merci CEDERAVIC de ton aide.

Je vais essayer de comprendre ce que tu viens de me donner.

En fait, toute la difficulté, c'est que justement je ne connais pas le nombre de parametres, ni les fonctions que je vais appeller.
Comme je le dit toujours, moins on s'y connais, plus on en demande...c'est d'ailleurs a ça que l'on reconnait "quinquin" qui y connait rien....
C'est parce que y demande toujours des trucs impossibles...si y s'y connaissait un peu, y poserait pas ce genre de question :mrgreen:

En fait, je trouve que FRED il est trop fort, alors tout seul dans mon bureau, je me la pete, et je joue au "FREDAL POURSUIT" :D
Le jeu y consiste a reinventer les fonctions de FRED, mais en une seule ligne, et avec tout le jus dedans :D

C'est vrai FRED il a tendance a oublier que y'a des brouettes comme moi qui voudraient aussi programmer...
Et y dit des "Yaka"...."Yapuka"...."yfokon".."toraka"...enfin bref...noir de mots japonais...et KCC y parle pas japonais :?
D'ailleurs est ce qu'un aveugle y veut pas voir ???
Un cul de jatte y voudrais pas courrir ??? :roll:
Et ben KCC y veut programmer, meme si il est monté tres fin :?

C'est vrai l'appel des fonctions, c'etait simple avant, mais maintenant que faut rajouter des adresse mails de partout et en plus il faut toujours verifier le retour etc...
Bah je me suis dit que ça vaudrait peut etre le coup de creer une procedure "GENERIQUE" qui servirait pour toutes les fonctions d'une DLL.

Tu n'avait surement pas suivi, mais comme je l'ai dit au dessus pendant un mois et demi, j'ai cassé les grelots a SROD, CPL.BATOR :(, XOMBIE, DOBRO et plein d'autre...car je voulais en une ligne retourner un tableau de string d'une DLL.
Pour moi ça a été un challenge de la mort, mais mon acharnement a payé.
J'ai maintenant une fonction du style :

Code : Tout sélectionner

Dim TabloARemplir(0)
TabloDllEnLocal(*strPtr.INTEGER, Array TabloARemplir.s(1))
et hop, deux lignes et j'me retrouve avec mon tableau tout rempli.

Tu peux pas savoir, des fois je l'admire cette fonction, avec elle j'promene les tableaux de string comme mémé son yorkshire à poil durs, de la dll a l'exe et meme avec VB.
C'est a la limite de la giclette :D

Alors je me suis dit, en moi meme, ne serait il pas possible de creer une fonction, qui s'occupe de verifier le retour pointeur, et aussi qui tiendrait en une seule ligne avec des parametres simples.
Car le prototypes j'ai encore du mal, et comme j'ai l'impression que je vais m'en servir a chaque fois que je perd un bras, je me suis dit je met le maximum dans cette procedure, et comme ça je peux appeller facilement une fonction de DLL en une seule ligne du style :roll:

Code : Tout sélectionner

CallProtoString(0, "MessageBox2", "Hello 1|2|3|4|5")
CallFunctionString(0, "MessageBox2", "Hello 1|2|3|4|5")
Et avec ça pas besoin de @, ni de Peeks() et pas de plantage...au pire ça retourne rien :D

D'ailleur, si un jour je le croise FRED, et ben je lui causerais du pays
Parce que depuis le temps, il aurait aussi pu creer un genre de variant, mi figue mi raisin, qui permettrait de passer en argument aussi bien un string qu'un nombre et apres on testerait, si c'est l'un ou l'autre.
Ce serait trop cool 8)
Ce sera dans MA TODO LIST, c'est à dire la liste des choses que FRED y fera jamais, comme UseGIFmageDecoder, les Retour a la ligne, les variants et plein de choses qui me font dire qu'on doit pas avoir la meme liste :mrgreen:

Alors en attend,....... FREDCC y bricole des fonctions, avec du scotch et des bouts de tuyaux usagés :?

Re: Simplifier et proteger les appels fonction string à une DLL

Publié : lun. 21/déc./2009 17:30
par cederavic
Je penses avoir compris ce que tu voulais globalement, mais il reste quelques points sombres... Comment veux-tu appeler une fonction dont tu ne connait ni le nom ni le nombre de paramètres (et donc leur type)? C'est comme demander à un babouin muet de te crier la combinaison gagnante de l'euro-million en patois 8O
A moins qu'en fait tu connaisse les définitions des fonctions (donc à intégrer dans le programme) et que tu veuille qu'une fonction "globale" pour les appeler seulement par le noms sans te soucier du nombre / type des paramètre?
Punaise tu m'embrouille là! :lol:

Essaye ça :
Programme

Code : Tout sélectionner

Procedure.s CallKCCFunction(Lib.l, FunctionName.s, Parameters.s="")
  If IsLibrary(Lib) 
    If GetFunction(Lib, FunctionName)
      Select FunctionName.s
      
        Case "MessageBox"
          Parm1.s = StringField(Parameters, 1, "|")
          *Result = CallFunction(Lib, FunctionName, @Parm1)
        
        Case "MessageBox2"
          Parm1.s = StringField(Parameters, 1, "|")
          Parm2.l = Val(StringField(Parameters, 2, "|"))
          *Result = CallFunction(Lib, FunctionName, @Parm1, Parm2)
        
        Case "MessageBox3"
          Parm1.s = StringField(Parameters, 1, "|")
          Parm2.l = Val(StringField(Parameters, 2, "|"))
          Parm3.f = ValF(StringField(Parameters, 3, "|"))
          *Result = CallFunction(Lib, FunctionName, @Parm1, Parm2, Parm3)
        
        Case "MessageBox4"
          Parm1.s = StringField(Parameters, 1, "|")
          Parm2.l = Val(StringField(Parameters, 2, "|"))
          Parm3.f = ValF(StringField(Parameters, 3, "|"))
          Parm4.s = StringField(Parameters, 4, "|")
          *Result = CallFunction(Lib, FunctionName, @Parm1, Parm2, Parm3, @Parm4)
        
        Case "MessageBox5"
          Parm1.s = StringField(Parameters, 1, "|")
          Parm2.l = Val(StringField(Parameters, 2, "|"))
          Parm3.f = ValF(StringField(Parameters, 3, "|"))
          Parm4.s = StringField(Parameters, 4, "|")
          Parm5.l = Val(StringField(Parameters, 5, "|"))
          *Result = CallFunction(Lib, FunctionName, @Parm1, Parm2, Parm3, @Parm4, Parm5)
        
        Case "Fake"
          *Result = CallFunction(Lib, FunctionName)
          
      EndSelect
    Else
      ProcedureReturn "Error FunctionName"
    EndIf
  Else
    ProcedureReturn "Error LibID"
  EndIf
  
  If *Result <> #Null
    ProcedureReturn PeekS(*Result)
  Else
    ProcedureReturn "*Result is null"
  EndIf
  
EndProcedure
  
OpenLibrary(0, "DllMessageBox.dll")
  Debug CallKCCFunction(0, "MessageBox", "Test")
  Debug CallKCCFunction(0, "MessageBox2", "Tset|2")
  Debug CallKCCFunction(0, "MessageBox3", "Etst|4|3.14")
  Debug CallKCCFunction(0, "MessageBox4", "Sett|78|14.3|Hoo")
  Debug CallKCCFunction(0, "MessageBox5", "Ttse|23|4.13|Ooh|987654321")
  Debug CallKCCFunction(0, "Fake")
CloseLibrary(0)
Dll

Code : Tout sélectionner

ProcedureDLL.s MessageBox(Parm1.s)
Texte$ = Parm1
MessageRequester("Message de la Dll 2", Texte$)
ProcedureReturn Texte$
EndProcedure

ProcedureDLL.s MessageBox2(Parm1.s, Parm2.l)
Texte$ = Parm1 + " " + Str(Parm2)
MessageRequester("Message de la Dll 2", Texte$)
ProcedureReturn Texte$
EndProcedure

ProcedureDLL.s MessageBox3(Parm1.s, Parm2.l, Parm3.f)
Texte$ = Parm1 + " " + Str(Parm2) + " " + StrF(Parm3)
MessageRequester("Message de la Dll 3", Texte$)
ProcedureReturn Texte$
EndProcedure

ProcedureDLL.s MessageBox4(Parm1.s, Parm2.l, Parm3.f, Parm4.s)
Texte$ = Parm1 + " " + Str(Parm2) + " " + StrF(Parm3) + " " + Parm4
MessageRequester("Message de la Dll 4", Texte$)
ProcedureReturn Texte$
EndProcedure

ProcedureDLL.s MessageBox5(Parm1.s, Parm2.l, Parm3.f, Parm4.s, Parm5.l)
Texte$ = Parm1 + " " + Str(Parm2) + " " + StrF(Parm3) + " " + Parm4 + " " + Str(Parm5)
MessageRequester("Message de la Dll 5", Texte$)
ProcedureReturn Texte$
EndProcedure

ProcedureDLL.l Fake()
  ProcedureReturn 0
EndProcedure
La fonction Fake est là pour simuler le retour d'un pointeur null :!:

Re: Simplifier et proteger les appels fonction string à une DLL

Publié : lun. 21/déc./2009 18:49
par Kwai chang caine
Ouaahhhhh je t'aime CEDERAVIC !!!
J'ai cru que personne y prenait au serieux KCC encore une fois :(

Et pourtant c'est quand meme pas con ce que je cherche à faire ??? :roll:
Euuuuh!!! Non en fin de compte, ne me donne pas ton avis, aujourd'hui j'ai eu une bonne journée :lol: :lol:

Alors la...KCC il a mis sa tenue du KGB avec le fouet et le string en cuir noir, y s'est pas trompé de sens, c'est facile....marron derriere et jaune devant, y'a les couleurs a l'interieur, et il a torturé ton code dans tous les sens :twisted:
Mon vieux, c'est un dur de dur, ton code....il a pas planté une seule fois
T'es vraiment un chef... 8)
Mon sauveur a écrit :Comment veux-tu appeler une fonction dont tu ne connait ni le nom ni le nombre de paramètres
Bah si,........ qu'on a le nom de la fonction dans FunctionName :D
On a aussi l'ID de la DLL :D
Et les parametres, on peut en mettre tant qu'on veut entre les barres.
Mais je me suis pensé que si j'allais jusqu'a 10, je crois que j'aurais fait le tour....t'en connait beaucoup toi des API ou des fonctions meme a toi qui depasse les 10 parametres ???? :roll:

La ou tu as raison, c'est sur le type des variables :(
C'est pourquoi j'ai pensé a passer les parametres dans une string, comme ça on peut passer les chiffres comme les textes :D
On pourrait par exemple leur donné une extension du style

Code : Tout sélectionner

CallKCCFunction(Lib.l, FunctionName.s, "Coucou.s|1251545.l|12.i|125.25.f")
Le premier c'est du texte, le second un long, le troisieme un integer, le 4e un decimal
Remarque je peux aussi faire un code pour reperer si c'est un texte ça c'est facile :wink:
Bon je sais c'est la partie la plus degueue de mon idée....
Peut etre en auras tu une autre au niveau des parametres ??

J'avais aussi pensé a faire

Code : Tout sélectionner

CallKCCFunction(Lib.l, FunctionName.s, a.l = 0, b.l = 0, d.l = 0, etc ....)
En donnant a chaque fois soit les pointeurs des variables, soit un nombre.
Mais je pense que c'est beaucoup plus dur a gerer, car comment reconnaitre un pointeur memoire d'un grand chiffre comme 35435437 :roll:

Alors je suis reparti sur les strings, c'est plus souple :D
Ah si seulement FRED il avait accepté de creer les variants...VB pour une fois lui y se demmerde, j'sais pas comment y fait, mais y se demmerde 8)
Et j'aime pas dire que VB est meilleur. :?

Sans dire d'aller jusqu'a la gestion des Variables made in VB, mais il aurait pu accepter que l'on puisse mettre dans une variable de parametre de procedure un nombre ou un texte.
Ce qui est fou, c'est qu'il avait commencé a le faire avec son callfunction, car je me suis apercu avec stupeur que tu pouvais mettre soit l'adresse de la variable, soit la variable jusqu'a la 4.30 8O
Car ça marche dans les deux cas...

Et ben non....il a fait machine arriere :?
Bon...les voies du seigneur son impenetrables...et lui seul connait le chemin, meme si KCC y se tord les pingles tous les jours sur ces routes caillouteuses :(
Mais t'avoueras que c'est dommage :(

J'ai vu que tu as utilisé les callfunctions...crois tu qu'avec les prototrucs on peut faire pareil ???
Parce que connaissant notre FRED un de ces jours,y risque de nous enlever notre jouet de la bouche et nous tapoter sur les mains en nous disant : "Non non non !!! c'est pas bien de mettre les CallFunctions a la bouche, c'est pas bien...papa FRED y va les jeter comme ça il sera plus obligé de vous gronder ..."
Et la un beau matin de pleine lune a l'aurore d'une nouvelle version....PAF !!!!plus de callfunction 8O

Et la KCC, y va etre en colere, parce que il aura encore avancé, et il aura des centaines de fonctions a remodifier :?
Qu'en penses tu ??? :roll:

Re: Simplifier et proteger les appels fonction string à une DLL

Publié : lun. 21/déc./2009 22:01
par cederavic
A force on va y arriver....
Voila une autre version, qui elle accepte toute sorte de paramètre (jusqu'à 10, mais ça après tu peux en rajouter) même des structures et sans callfunction. Mais par-contre il faut obligatoirement passer par des pointeurs, c'est le gros inconvénient de la chose. Il faut aussi bien définir les prototypes et faire les bonnes conversions de type dans le select/case de CallKCCFunction()

Et tu peux même "lier" directement les API (voir exemple dans le code en dessous, je récupère et change la position du curseur via l'api)
Seule la source sur programme à été modifiée :

Code : Tout sélectionner

OpenLibrary(0, "DllMessageBox.dll")
OpenLibrary(1, "User32.dll")

Prototype.l MessageBox_Proto(Parm1.s)                                      : Global ProtoMessageBox.MessageBox_Proto   = GetFunction(0, "MessageBox")
Prototype.l MessageBox2_Proto(Parm1.s, Parm2.l)                            : Global ProtoMessageBox2.MessageBox2_Proto = GetFunction(0, "MessageBox2")
Prototype.l MessageBox3_Proto(Parm1.s, Parm2.l, Parm3.f)                   : Global ProtoMessageBox3.MessageBox3_Proto = GetFunction(0, "MessageBox3")
Prototype.l MessageBox4_Proto(Parm1.s, Parm2.l, Parm3.f, Parm4.s)          : Global ProtoMessageBox4.MessageBox4_Proto = GetFunction(0, "MessageBox4")
Prototype.l MessageBox5_Proto(Parm1.s, Parm2.l, Parm3.f, Parm4.s, Parm5.l) : Global ProtoMessageBox5.MessageBox5_Proto = GetFunction(0, "MessageBox5")
Prototype.l Fake_Proto()                                                   : Global ProtoFake.Fake_Proto               = GetFunction(0, "Fake")


Prototype.l CursorPosition_Proto(*lpPoint.Point)                           : Global ProtoCursorPosition.CursorPosition_Proto = GetFunction(1, "GetCursorPos")
Prototype.l PositionCursor_Proto(x.l, y.l)                                 : Global ProtoPositionCursor.PositionCursor_Proto = GetFunction(1, "SetCursorPos")



Procedure.l CallKCCFunction(FunctionName.s, *Parm1.l=0, *Parm2.l=0, *Parm3.l=0, *Parm4.l=0, *Parm5.l=0, *Parm6.l=0, *Parm7.l=0, *Parm8.l=0, *Parm9.l=0, *Parm10.l=0)

  Select FunctionName.s
  
    Case "MessageBox"
      *Result = ProtoMessageBox(PeekS(*Parm1))
    
    Case "MessageBox2"
      *Result = ProtoMessageBox2(PeekS(*Parm1), PeekL(*Parm2))
      
    Case "MessageBox3"
      *Result = ProtoMessageBox3(PeekS(*Parm1), PeekL(*Parm2), PeekF(*Parm3))
      
    Case "MessageBox4"
      *Result = ProtoMessageBox4(PeekS(*Parm1), PeekL(*Parm2), PeekF(*Parm3), PeekS(*Parm4))
      
    Case "MessageBox5"
      *Result = ProtoMessageBox5(PeekS(*Parm1), PeekL(*Parm2), PeekF(*Parm3), PeekS(*Parm4), PeekL(*Parm5))

    Case "Fake"
      *Result = ProtoFake()
      
    Case "CursorPosition"
      *Result = ProtoCursorPosition(*Parm1)
      
    Case "PositionCursor"
      *Result = ProtoPositionCursor(PeekL(*Parm1), PeekL(*Parm2))
      
  EndSelect
  
  ProcedureReturn *Result
  
EndProcedure
  
  
Parm1.s = "Test"
Parm2.l = 2
Parm3.f = 3.14
Parm4.s = "Estt"
Parm5.l = 10

Debug PeekS(CallKCCFunction("MessageBox", @Parm1))
Debug PeekS(CallKCCFunction("MessageBox2", @Parm1, @Parm2))
Debug PeekS(CallKCCFunction("MessageBox3", @Parm1, @Parm2, @Parm3))
Debug PeekS(CallKCCFunction("MessageBox4", @Parm1, @Parm2, @Parm3, @Parm4))
Debug PeekS(CallKCCFunction("MessageBox5", @Parm1, @Parm2, @Parm3, @Parm4, @Parm5))
Debug CallKCCFunction("Fake")


Cursor.point

CallKCCFunction("CursorPosition", @Cursor)
Text.s = "Position du curseur : " + Str(Cursor\x) + " ; " + Str(Cursor\y)
CallKCCFunction("MessageBox", @Text)

x.l = Cursor\x + 150
y.l = Cursor\y + 200
CallKCCFunction("PositionCursor", @x, @y)

CallKCCFunction("CursorPosition", @Cursor)
Text.s = "Position du curseur : " + Str(Cursor\x) + " ; " + Str(Cursor\y)
CallKCCFunction("MessageBox", @Text)

CloseLibrary(0)
CloseLibrary(1)

Re: Simplifier et proteger les appels fonction string à une DLL

Publié : mar. 22/déc./2009 8:34
par Kwai chang caine
CEDERAVIC pourquoi t'as arretté la programmation ???? 8O
On ne se connait pas beaucoup, car tu es parti quand je suis arrivé presque....
En fin de compte, je t'ai "remplacé"....bonjour le cadeau :lol:

Je ne sais pas si le forum te manques (Peut etre un peu, si tu reviens nous voir....), mais en tout cas ...tu manques au forum :(
A mes debut, y'avait une sacré equipe, Toi, Flype, Nico, Droopy, Comtois, Soldat, Djes, Case, Dobro, Cpl.Bator :(, Brossden, Lna (Fifille :mrgreen:), Tonton, Denis, Chris (J'espere qu'il est pas tombé en moto :roll:), notre ami pour toujours WolfJeremy :( , Dr dri et j'en oublie surement et pas les moins bons :(

Heureusement des nouveaux copains super gentils sont arrivés...mais bon le forum c'est pas un ascenseur, meme si il nous eleve tous les jours :? (Ouaaah KCC il est bon "c'lui la" de jeux de mots...prend un crayon FRED...prend un crayon :mrgreen:)
C'est pas parce que des nouveaux arrivent qu'il faut que les anciens sortent :twisted:

T'es vraiment un ange, alors la tu m'as mis sur la bonne voie.
Grace à toi, je devrais pouvoir continuer et peaufiner ma "super" fonction 8)

Par contre, le proto il est chatouilleux .....c'est plus sensible que le callfunction.
Il a pas résisté a ma culotte de cuir noir....parce que si j'oublie un parametre.....bah y'a erreur :(

Mais bon peut etre que je pourrais proteger ça.
Je vais regarder, encore merci CEDERAVIC, tu m'enleve une grosse epine du pied.
C'est une fonction qui devrait me servir des milliers de fois, si j'arrive a aller au bout 8)

Je te souhaite une excelente journée

Re: Simplifier et proteger les appels fonction string à une DLL

Publié : mar. 22/déc./2009 10:04
par cederavic
J'ai pas totalement arrêté la prog, mais disons que je suis beaucoup moins ambitieux qu'avant... Mais ça m'empêche pas de me tenir à jours et de passer sur le forum (la plupart du temps j'étais pas en anonyme, c'est pour ça qu'on ne voyait pas :p)

Pour l'oublie de paramètres, suffit d'intégrer un mini système d'erreur qui va vérifier que les pointeur envoyés (et retournés tant qu'à faire) ne sont pas null, chose que je viens de faire :)
Essaye ça, j'ai fait exprès de mettre des erreurs :

Code : Tout sélectionner

Enumeration
  #KCC_ERROR_Parm1
  #KCC_ERROR_Parm2
  #KCC_ERROR_Parm3
  #KCC_ERROR_Parm4
  #KCC_ERROR_Parm5
  #KCC_ERROR_Parm6
  #KCC_ERROR_Parm7
  #KCC_ERROR_Parm8
  #KCC_ERROR_Parm9
  #KCC_ERROR_Parm10
  
  #KCC_ERROR_ReturnNull
  #KCC_ERROR_FunctionName
EndEnumeration

Structure FunctionDef_Struct
  NbParms.b
  ReturnData.b
EndStructure

OpenLibrary(0, "DllMessageBox.dll")
OpenLibrary(1, "User32.dll")

Prototype.l MessageBox_Proto(Parm1.s)                                      : Global ProtoMessageBox.MessageBox_Proto   = GetFunction(0, "MessageBox")
Prototype.l MessageBox2_Proto(Parm1.s, Parm2.l)                            : Global ProtoMessageBox2.MessageBox2_Proto = GetFunction(0, "MessageBox2")
Prototype.l MessageBox3_Proto(Parm1.s, Parm2.l, Parm3.f)                   : Global ProtoMessageBox3.MessageBox3_Proto = GetFunction(0, "MessageBox3")
Prototype.l MessageBox4_Proto(Parm1.s, Parm2.l, Parm3.f, Parm4.s)          : Global ProtoMessageBox4.MessageBox4_Proto = GetFunction(0, "MessageBox4")
Prototype.l MessageBox5_Proto(Parm1.s, Parm2.l, Parm3.f, Parm4.s, Parm5.l) : Global ProtoMessageBox5.MessageBox5_Proto = GetFunction(0, "MessageBox5")
Prototype.l Fake_Proto()                                                   : Global ProtoFake.Fake_Proto               = GetFunction(0, "Fake")


Prototype.l CursorPosition_Proto(*lpPoint.Point)                           : Global ProtoCursorPosition.CursorPosition_Proto = GetFunction(1, "GetCursorPos")
Prototype.l PositionCursor_Proto(x.l, y.l)                                 : Global ProtoPositionCursor.PositionCursor_Proto = GetFunction(1, "SetCursorPos")

Global NewMap FunctionDef.FunctionDef_Struct()
  FunctionDef("MessageBox")\NbParms     = 1
  FunctionDef("MessageBox")\ReturnData  = #True
  
  FunctionDef("MessageBox2")\NbParms    = 2
  FunctionDef("MessageBox2")\ReturnData = #True
  
  FunctionDef("MessageBox3")\NbParms    = 3
  FunctionDef("MessageBox3")\ReturnData = #True
  
  FunctionDef("MessageBox4")\NbParms    = 4
  FunctionDef("MessageBox4")\ReturnData = #True
  
  FunctionDef("MessageBox5")\NbParms    = 5
  FunctionDef("MessageBox5")\ReturnData = #True
  
  FunctionDef("Fake")\NbParms     = 0
  FunctionDef("Fake")\ReturnData  = #True
  
  FunctionDef("CursorPosition")\NbParms     = 1
  FunctionDef("CursorPosition")\ReturnData  = #False
  
  FunctionDef("PositionCursor")\NbParms     = 2
  FunctionDef("PositionCursor")\ReturnData  = #False
    

Procedure.b KCCFuncError(FunctionName.s, ErrorID.b)

  Select ErrorID
  
    Case #KCC_ERROR_Parm1
      MessageRequester("KCC Error Func", "Function : " + FunctionName + Chr(13) + "Error : Parm1", 0)
      
    Case #KCC_ERROR_Parm2
      MessageRequester("KCC Error Func", "Function : " + FunctionName + Chr(13) + "Error : Parm2", 0)
      
    Case #KCC_ERROR_Parm3
      MessageRequester("KCC Error Func", "Function : " + FunctionName + Chr(13) + "Error : Parm3", 0)
      
    Case #KCC_ERROR_Parm4
      MessageRequester("KCC Error Func", "Function : " + FunctionName + Chr(13) + "Error : Parm4", 0)
      
    Case #KCC_ERROR_Parm5
      MessageRequester("KCC Error Func", "Function : " + FunctionName + Chr(13) + "Error : Parm5", 0)
      
    Case #KCC_ERROR_Parm6
      MessageRequester("KCC Error Func", "Function : " + FunctionName + Chr(13) + "Error : Parm6", 0)
      
    Case #KCC_ERROR_Parm7
      MessageRequester("KCC Error Func", "Function : " + FunctionName + Chr(13) + "Error : Parm7", 0)
      
    Case #KCC_ERROR_Parm8
      MessageRequester("KCC Error Func", "Function : " + FunctionName + Chr(13) + "Error : Parm8", 0)
      
    Case #KCC_ERROR_Parm9
      MessageRequester("KCC Error Func", "Function : " + FunctionName + Chr(13) + "Error : Parm9", 0)
      
    Case #KCC_ERROR_Parm10
      MessageRequester("KCC Error Func", "Function : " + FunctionName + Chr(13) + "Error : Parm10", 0)
      
    Case #KCC_ERROR_ReturnNull
      MessageRequester("KCC Error Func", "Function : " + FunctionName + Chr(13) + "Error : Returned ptr is null", 0)
    
    Case#KCC_ERROR_FunctionName
      MessageRequester("KCC Error Func", "Function : " + FunctionName + Chr(13) + "Error : Function isn't defined", 0)
      
  EndSelect

EndProcedure

Procedure.l CallKCCFunction(FunctionName.s, *Parm1.l=0, *Parm2.l=0, *Parm3.l=0, *Parm4.l=0, *Parm5.l=0, *Parm6.l=0, *Parm7.l=0, *Parm8.l=0, *Parm9.l=0, *Parm10.l=0)
  *Result.l = 0
  Error.b = #False
  
  NbParms.b = FunctionDef(FunctionName)\NbParms
  If NbParms > 0
    If Not *Parm1 : KCCFuncError(FunctionName, #KCC_ERROR_Parm1) : Error = #True : EndIf
  EndIf
  If NbParms > 1
    If Not *Parm2 : KCCFuncError(FunctionName, #KCC_ERROR_Parm2) : Error = #True : EndIf
  EndIf
  If NbParms > 2
    If Not *Parm3 : KCCFuncError(FunctionName, #KCC_ERROR_Parm3) : Error = #True : EndIf
  EndIf
  If NbParms > 3
    If Not *Parm4 : KCCFuncError(FunctionName, #KCC_ERROR_Parm4) : Error = #True : EndIf
  EndIf
  If NbParms > 4
    If Not *Parm5 : KCCFuncError(FunctionName, #KCC_ERROR_Parm5) : Error = #True : EndIf
  EndIf
  If NbParms > 5
    If Not *Parm6 : KCCFuncError(FunctionName, #KCC_ERROR_Parm6) : Error = #True : EndIf
  EndIf
  If NbParms > 6
    If Not *Parm7 : KCCFuncError(FunctionName, #KCC_ERROR_Parm7) : Error = #True : EndIf
  EndIf
  If NbParms > 7
    If Not *Parm8 : KCCFuncError(FunctionName, #KCC_ERROR_Parm8) : Error = #True : EndIf
  EndIf
  If NbParms > 8
    If Not *Parm9 : KCCFuncError(FunctionName, #KCC_ERROR_Parm9) : Error = #True : EndIf
  EndIf
  If NbParms > 9
    If Not *Parm10 : KCCFuncError(FunctionName, #KCC_ERROR_Parm10) : Error = #True : EndIf
  EndIf
  
  If Error = #True
    ProcedureReturn @""
  EndIf
  
  Select FunctionName.s
  
    Case "MessageBox"
      *Result = ProtoMessageBox(PeekS(*Parm1))
    
    Case "MessageBox2"
      *Result = ProtoMessageBox2(PeekS(*Parm1), PeekL(*Parm2))
      
    Case "MessageBox3"
      *Result = ProtoMessageBox3(PeekS(*Parm1), PeekL(*Parm2), PeekF(*Parm3))
      
    Case "MessageBox4"
      *Result = ProtoMessageBox4(PeekS(*Parm1), PeekL(*Parm2), PeekF(*Parm3), PeekS(*Parm4))
      
    Case "MessageBox5"
      *Result = ProtoMessageBox5(PeekS(*Parm1), PeekL(*Parm2), PeekF(*Parm3), PeekS(*Parm4), PeekL(*Parm5))

    Case "Fake"
      *Result = ProtoFake()
      
    Case "CursorPosition"
      *Result = ProtoCursorPosition(*Parm1)
      
    Case "PositionCursor"
      *Result = ProtoPositionCursor(PeekL(*Parm1), PeekL(*Parm2))
      
    Default
      KCCFuncError(FunctionName, #KCC_ERROR_FunctionName)
      
  EndSelect
  
  If Not *Result And FunctionDef(FunctionName)\ReturnData = #True
    KCCFuncError(FunctionName, #KCC_ERROR_ReturnNull)
    ProcedureReturn @""
  EndIf
  
  ProcedureReturn *Result
  
EndProcedure
  
  
Parm1.s = "Test"
Parm2.l = 2
Parm3.f = 3.14
Parm4.s = "Estt"
Parm5.l = 10

Debug PeekS(CallKCCFunction("MessageBox"))
Debug PeekS(CallKCCFunction("MessageBox2", @Parm1, @Parm2))
Debug PeekS(CallKCCFunction("MessageBox3", @Parm1, @Parm2, @Parm3))
Debug PeekS(CallKCCFunction("MessageBox4", @Parm1, @Parm2, @Parm3, @Parm4))
Debug PeekS(CallKCCFunction("MessageBox5", @Parm1, @Parm2, @Parm3, @Parm4, @Parm5))
Debug CallKCCFunction("Fake")


Cursor.point

CallKCCFunction("CursorPosition", @Cursor)
Text.s = "Position du curseur : " + Str(Cursor\x) + " ; " + Str(Cursor\y)
CallKCCFunction("MessageBox", @Text)

x.l = Cursor\x + 150
y.l = Cursor\y + 200
CallKCCFunction("PositionCursor", @x, @y)

CallKCCFunction("CursorPosition", @Cursor)
Text.s = "Position du curseur : " + Str(Cursor\x) + " ; " + Str(Cursor\y)
CallKCCFunction("MessageBox", @Text)

CallKCCFunction("Zoubida")

CloseLibrary(0)
CloseLibrary(1)
Il y a encore surement beaucoup de choses à améliorer dans ce code...

Re: Simplifier et proteger les appels fonction string à une DLL

Publié : mar. 22/déc./2009 11:00
par Kwai chang caine
Merci CEDERAVIC

Je viens d'essayer ton code et effectivement, y'a une erreur mais est elle voulue vraiment ????
Parce que j'ai le cordon rouge en 152 :roll:

Ce matin grace a ton code, j'ai essayé de comprendre les prototruc...
Et 2 heures apres, je viens de comprendre un truc, que FRED il aurait pu mettre dans l'aide.
Parce que maintenant qu'il nous "force" a passer par ces trucs, il aurait du etoffer l'aide.
Elle commence d'ailleurs par dire que KCC y devrait pas l'utiliser...bonjour l'acceuil :?

Code : Tout sélectionner

Pour les programmeurs chevronnés. 
Moi la seule chose que j'ai eu de chevronné, c'etait les voitures de mon papa, car il adorait les citroens :roll:

Bref, je viens de comprendre, que on ne peut mettre de parametres par defaut QUE SI dans la fonction elles sont par defaut aussi.

Exemple qui marche pas:

Code : Tout sélectionner

Prototruc Format(Param1, Param2.s = "",  Param3 = "")

Procedure FonctionGenerique(Param1)
EndProcedure
Exemple qui marche :

Code : Tout sélectionner

Prototruc Format(Param1, Param2.s = "",  Param3 = "")

Procedure FonctionGenerique(Param1, Param2.s = "",  Param3 = "")
EndProcedure
Bon peut etre que tout le monde avait compris, sauf moi :oops:
Car la phrase de dieu est ambigue
Dieu a écrit :Les paramètres en fin de prototype peuvent avoir une valeur par défaut (une expression constante est requise). Les paramètres ayant une valeur par défaut pourront être omis lors de l'appel du prototype, la valeur par défaut de chaque paramètre manquant sera utilisée.
Ca veut pas dire que les parametres devront aussi etre par defaut dans la procedure.
A aucun moment il ne parle d'elle :(
J'ai perdu 3 heures a cause de ça.


Kcc il aurait mis :

ATTENTION !!! la declaration prototype doit avoir strictement le meme format que la procedure qu'il appelle
Et la c'est clair :?

Deja c'est EESAU qui m'a fait comprendre que les prototype, c'est comme un masque, une structure pour une variable, une classe pour VB...en fin de compte c'est un moule avec lequel on "formate" les variables pour qu'elles soit au format de la fonction :roll:
Ca aussi il aurait pu le marquer, on comprendrais pourquoi, il ne faut les declarer qu'une fois, comme les structure, car je suppose que c'est gravé dans le marbre au meme titre que les constantes :roll:

Et c'est TINMAN qui m'a gentillement expliqué que les protozoaires, ça prenait pas de memoire vive, comme les constantes, c'est pour ça que je les ai comparé a elles.
Tant que tu fourre pas une variable dedans, tu peux ecrire des centaines de "Format" de proto...et ben ça charge pas le programme, ni la memoire....
Alors c'est peut etre ce que je vais faire, pour ma fonction, declarer toutes les possibilités :roll:
JE sais ça en fait une centaine, mais si ça bouffe pas de memoire et que ça gene pas le programme, ce sera peut etre un peu plus long a la compil, mais apres j'aurais un appel de fonction super simple :D

Un tuto sur les protomachins serait drolement nécéssaire...moi je l'aurais bien fait, mais j'ecris tellement de conneries....alors quand c'est pour rigoler, je peux me lacher....mais la honte si tu te la pete a expliquer aux autres et que t'as rien compris :oops:

Re: Simplifier et proteger les appels fonction string à une DLL

Publié : mar. 22/déc./2009 11:12
par Kwai chang caine
L'abruti de service a écrit :Merci CEDERAVIC
Je viens d'essayer ton code et effectivement, y'a une erreur mais est elle voulue vraiment ????
Parce que j'ai le cordon rouge en 152
Excuse MOI j'suis vraiment une tache....
J'avais modifié ta DLL, c'est pour ça que ça marchait pas....
Depuis 3 heures que je trifouille...j'ai une palanquée de DLL et de codes :oops:

Re: Simplifier et proteger les appels fonction string à une DLL

Publié : mar. 22/déc./2009 11:19
par cederavic
Tu as quoi comme erreur ligne 152? car chez moi ça tourne niquel...

Je comprend bien ce que tu voudrais faire, mais je sais pas si c'est vraiment faisable en PB car tu ne peux pas metre n'importe quoi en parametre, il faut que les types correspondent... C'est pas vraiment les prototype le problème, comme tu le dis ce n'est qu'un mask.
La seule solution que je vois pour faire quelque chose de propre serait de pre-process le code source, et encore, il faudrait la définition de toutes les fonctions que tu veux utilisé (nom, parms et leur type, retour et son type)

Mon code est très gadget et pas super souple, mais faut faire avec ce qu'on a hein :roll:

Re: Simplifier et proteger les appels fonction string à une DLL

Publié : mar. 22/déc./2009 15:47
par Kwai chang caine
Ouaih...j'ai bien peur que tu ai raison :(
Depuis le temps, je m'etais dit qu'avec toutes les nouvelles fonctions on pourrait peut etre faire mieux :(

En fait, encore une chose pour la TODO LIST, qui aurait été géniale, c'est de pouvoir appeler une variable par son nom....
Je sais pas si un language compilé sait faire ça etant donné qu'une fois compilé le nom de la variable disparait :(
Donc autant dire que ce n'est pas demain la veille...

Bon bah, je crois que KCC y va la remetre dans sa culotte :(
J'avais trouvé une idée, mais c'est trop compliqué de gerer tous les formats, ça fait des milliers de possibilités
En tout cas merci beaucoup CEDERAVIC de ton aide, meme si on y est pas vraiment arrivé, l'important c'est d'essayer :wink:

Je te souhaite une excelente journée 8)

Re: Simplifier les appels fonction string d'une DLL [Impossible]

Publié : mar. 22/déc./2009 15:51
par cederavic
Qui ne tente rien n'a rien :P
Pis maintenant je sais utiliser les prototype ET les Map, donc du bénéfique en definitif 8)

Re: Simplifier les appels fonction string d'une DLL [Impossible]

Publié : mar. 22/déc./2009 15:53
par Kwai chang caine
Je te remercie de ta gentillesse, j'avais tellement honte de t'avoir fait perdre ton temps :oops: