BrokenArrow29
Messages postés110Date d'inscriptionvendredi 1 décembre 2006StatutMembreDernière intervention14 décembre 2011
-
11 oct. 2007 à 21:11
surfzoid
Messages postés463Date d'inscriptionvendredi 15 août 2003StatutMembreDernière intervention21 avril 2010
-
11 mars 2008 à 18:21
Bonjour,
j'obtiens cette erreur lorsque j'éxécute un petit programme :
"L'exception System.AccessViolationException n'a pas été gérée
Tentative de lecture ou d'écriture de mémoire protégée. Cela indique souvent qu'une autre mémoire est endommagée."
Détail: System.AccessViolationException "
Le programme lit une base de donnée et cherche le correspondant dans une autre base de donnée. L'erreur n'arrive jamais au meme endroit ou au meme enregistrement. Parcontre elle arrive toujours lorsque par une fonction (contenu dans un dll qui est en référence) attribue une valeur a une variable. C'est un peu weird ...
Merci de votre aide
A voir également:
Tentative de lecture ou d'écriture de mémoire protégée
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 12 oct. 2007 à 20:44
ALors déjà effectivement, comme je disais, tu n'instancie pas correctement tes string avant l'appel. Certes tu les instancies mais de longueur nulle. C'est à dire qu'aucune place n'est réservée en mémoire pour contenir la chaine de caractère. Hors il est probable que ta dll ne soit pas capable de créer une string en mémoire, elle doit juste se contenter (comme la quasi totalité des dlls api) de remplir une zone mémoire déjà occupée par la string à remplir. Dans ce cas là, avant de passer la string à la fonction, il faut veiller à ce que une zone mémoire suffisament grande est effectivement occupée par la dite string, c'est à dire que la string soit de longueur suffisament importante pour acceuillir sa nouvelle valeur.
Dans ton cas, si tant est que ce soit ça le problème, il faut que avant chaque appel, tu initialise chacune des strings avec suffisament de caractères pour que la zone réservée en mémoire soit suffisament grande. Ce qui donnerais le code suivant :
Dim PLAYERFIRST As String
Dim PLAYERCITY As String
Dim PLAYERLAST As String
Dim PLAYERindx As Integer = 0
'PARTIE DE CODE
'HandleEXH est
mon fichier ouvert de base de donnée.
For I = 0 To (TABLEINFO.RecordCount - 1)
PLAYERFIRST = New String(vbNullChar, 100)
PLAYERLAST = New String(vbNullChar, 100)
PLAYERCITY = New String(vbNullChar, 100)
PLAYERindx = New String(vbNullChar, 100)
TDBFieldGetValueAsString(HandleEXH, "SPBT", "FNME", I, PLAYERFIRST)
TDBFieldGetValueAsString(HandleEXH, "SPBT", "LNME", I, PLAYERLAST)
TDBFieldGetValueAsString(HandleEXH, "SPBT", "CITY", I, PLAYERCITY)
TDBFieldGetValueAsString(HandleEXH, "SPBT", "INDX", I, PLAYERindx)
Next
Autre problème possible :
Il te faut vérifier que la ligne de déclaration de ta dll correspond bien à une déclaration pour VB2005 et non pas VB6. En effet entre VB6 et VB2005, le type de variable a changé. Ainsi les integer (vb6) deviennent des short (ou Int16) en VB2005, les longs deviennent des integers.
Si donc ta déclaration avec des integers est prevu ppour VB6, pour l'utiliser avec VB2005, il te faut remplcer les integer par des shorts ou des Int16.
En espérant ne pas t'avoir trop embrouiller
---- Sevyc64 (alias Casy) ---- <hr size ="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
GEDDi
Messages postés206Date d'inscriptionlundi 22 novembre 1999StatutMembreDernière intervention 3 juillet 2008 11 oct. 2007 à 21:14
Ya fort à parier que ça vienne de la DLL, genre mémoire mal allouée, libération de mémoire anticipée, tentative d'acces à une zone mémoire qui a déjà été effacée mais dont le pointeur n'a pas été mis à NULL, ce genre de choses codées par des gruic gruiiic :)
BrokenArrow29
Messages postés110Date d'inscriptionvendredi 1 décembre 2006StatutMembreDernière intervention14 décembre 20111 11 oct. 2007 à 22:48
c'est que l'appel de la fonction (qui est storé dans la dll ) est dans une boucle qui va tournée autant fois qu'il ya des donnée dans la bd (genre 5 000 fois). Mais elle va donnée l'erreur des fois Exemple au 3000ieme enregistement sur le champ B et d'autre fois au 2800ieme sur un autre champ. Les fois d'avant elle fonctionne bien... Il semble pas avoir de relation avec le champ ou la donnée lu. Sa me semble comme si y aurais pas de mémoire disponible additionnelle. Pourtant j'ai 2gig de mémoire.
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 11 oct. 2007 à 22:53
Tu es en VB2005, comment déclare-tu les fonctions de ta dll ??? Il se peut que le type de variable que tu lui passe ne corresponde pas à ce qu'elle attent.
Autre point, est-ce que tes variables sont correctement instanciées avant de les passer à la dll. Ex, si tu lui passe une chaine de caractère qu'elle doit remplir, cette chaine doit au préalable etre correctement remplie avec suffisament de caractères pour qu'elle existe en mémoire.
Le mieux est que tu mette le bout de code qui pose problème.
---- Sevyc64 (alias Casy) ----# LE PARTAGE EST NOTRE FORCE #
BrokenArrow29
Messages postés110Date d'inscriptionvendredi 1 décembre 2006StatutMembreDernière intervention14 décembre 20111 12 oct. 2007 à 18:21
Voila ma déclaration de la fonction de la dll
Public
Declare
Function TDBFieldGetValueAsString
Lib
"F:\filedll\tdbaccess.dll" (
ByVal DBIndex
As
Integer,
ByVal TableName
As
String,
ByVal FieldName
As
String,
ByVal RecNo
As
Integer,
ByRef OutBuffer
As
String)
As
Boolean
Variable déclarer dans ma procedure
Dim
PLAYERFIRST
As
String
=
""
Dim PLAYERCITY AsString = ""
Dim PLAYERLAST
As
String =
""
Dim PLAYERindx
As
Integer = 0
'PARTIE DE CODE
'HandleEXH est mon fichier ouvert de base de donnée.
For
I = 0
To (TABLEINFO.RecordCount - 1) TDBFieldGetValueAsString(HandleEXH,
"SPBT",
"FNME", I, PLAYERFIRST)
TDBFieldGetValueAsString(HandleEXH,
"SPBT",
"LNME", I, PLAYERLAST)
TDBFieldGetValueAsString(HandleEXH,
"SPBT",
"CITY", I, PLAYERCITY)
TDBFieldGetValueAsString(HandleEXH,
"SPBT",
"INDX", I, PLAYERindx)
L'erreur peut arriver a n'importe quelle ligne des fonction TDBfield.. c'est aléatoire jusqu'a maintenant. Et sur n'importe quel enregistrement(la valeur de I est différence a chaque erreur.) La fonction TDBfield lit une valeur dans la table SPBT, sur le champ FNME etc. à l'enregistrement I et la place dans la variable au bout ex: PLAYERFIRST.
Voilà je ne sais pas si vous avez assez d'info pour m'aider
Merci!!!!!.
BrokenArrow29
Messages postés110Date d'inscriptionvendredi 1 décembre 2006StatutMembreDernière intervention14 décembre 20111 12 oct. 2007 à 21:25
Merci, Merci
ca fonctionne tres bien lorsque j'initialise la variable a chaque tour. C'est un détail que j'avais vue.
J'ai perdue une semaine à fouiller et changer mes procedures pour que tu me fasse découvrir qu'il fallait initialiser la variable a chaque tour de la routine pour la dll peuvent y inclure l'info.
Mais est ce type a visual studio 2005 ou si je l'avais fais en Vb6 ca aurait fonctionner sans l'initialiser a chaque tour ?
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 12 oct. 2007 à 21:42
Ca aurait été exactement pareil en VB6, c'est d'ailleurs comme ça que l'on fait lorsque l'on utilise les fonctions de l'api Windows.
Ceci est dû à la spécificité des variables de type string. Pour la pluspart des variables simples, ta variable dans le code représente une zone mémoire ou est réellement stocké la valeur de ta variable. Dans le cas des strings, la variable dans le code représente en mémoire, non pas une zone ou est stocké la chaine de caractère, mais une zone ou est stocké l'adresse d'une autre zone mémoire qui elle contiendra réellement la chaine de caractère. Dû au fonctionnement du traitement des string, cette derbière zone change en permanence de place, il est donc plus facile de stocké dans une variable fixe l'adresse d'une zone mémoire plutot que de modifier en permanance la position de cette variable et ainsi planter le programme qui aurait du mal à retrouver cette variable.
Pour ce qui est des dll, comme je te disais, généralement elles ne sont pas capable de créer de zone mémoire ou stockées les chaines. Elles ne font que copier les caractères dans une zone qui leurs a été indiqué. Mais si cette zone n'existe pas (string de longueur nulle par exemple) ou qu'elle est trop courte, la dll n'est pas capable de le savoir et va allègrement déborder sur les données qui suivent en les détruisant. Ces données étant corrompues, cela provoque soit un plantage, soit des erreurs, soit des violation d'accès.
C'est pour cela que lorsque tu passe une chaine de caractère à une dll de ce type qui doit y écrire dedant, cette chaine doit avoir au préalable été remplie pour qu'elle ait une longueur au moins égale (mais de préférence plus) que le nombre de caractères que va écrire la dll.
---- Sevyc64 (alias Casy) ----# LE PARTAGE EST NOTRE FORCE #
maximechaput
Messages postés2Date d'inscriptionmercredi 14 février 2007StatutMembreDernière intervention11 mars 2008 6 mars 2008 à 18:21
claude
J'avais le meme probleme je l'ai résolu en changant le type des paramtre
ex.: ByVal variable as long en ByVal variable as int32
j'ai eu plusieur bug avec les api(Dll) et j'ai du changer les types des parametre passé en Int32
si tu connait OLLY
tu execute le prog. sous olly et met un Breakpoint leur l'api que tu appelle et va voir si tes parametre sont bien typer.
Si tu peu me laisser un email je serait content de savoir si cela ta aider
surfzoid
Messages postés463Date d'inscriptionvendredi 15 août 2003StatutMembreDernière intervention21 avril 2010 7 mars 2008 à 10:13
il faudra que je test, olly c'est pour win32 ? tu le trouve ou ?
Ton prob sur le format de variable, il te faisait une erreur memoire systematique ou de façon complétement alléatoire ?
maximechaput
Messages postés2Date d'inscriptionmercredi 14 février 2007StatutMembreDernière intervention11 mars 2008 11 mars 2008 à 16:46
claude
Olly est sur internet tape Ollydbg et fait une recherche
lorsque tu entre les types des parametres si tu tu as un int 16 au lieu d'un int32.
l'api de la dll récupere pas la bonne adresse
donc au lieu d'aller lire en mémoire voulu il va lire sur une mémoire que se trouve sur pile car les valeurs récupérer par l'api sont biaiser
je te suggere fortement de te procurer OLLY avec ca va pouvoir t'assurer des parametre que tu
entre pour n'importe quelle api sont exact
et va comprendre pouquoi que l'appel des api sont aussi bizarre
En passant OLLY est le debugger utiliser par 90% de ceux qui decortique le code assembleur
tu n'aura pas besoin d'en connaiter beaucoup pour l'utiliser pour suivre les parametre passer au api de dll
si tu t'en serre envoi moi un email et je te dirai comment té,en servir pour suivre les api utiliser dans les
programmes comme visual basic et c++.
j'ai aussi remarquer que plusieurs api sur internet était mal documenter donc assure toi que tu as les bonnes informations
surfzoid
Messages postés463Date d'inscriptionvendredi 15 août 2003StatutMembreDernière intervention21 avril 2010 11 mars 2008 à 18:21
Merci
En fait je travail en colaboration avec l'equipe qui a ecrit la dll en C, mais a l'origine c'est une librairie Linux qui a été "porté" sous windows, bien entendu tout nouveau est accepté dans l'équipe, car c'est de l'opensource, tu serai d'accord (si comme tjr, le temp le permet) de participé ?