cs_EBArtSoft
Messages postés4525Date d'inscriptiondimanche 29 septembre 2002StatutModérateurDernière intervention22 avril 2019
-
30 juil. 2004 à 13:43
Polack77
Messages postés1098Date d'inscriptionmercredi 22 mars 2006StatutMembreDernière intervention22 octobre 2019
-
28 janv. 2008 à 15:25
Bonjour @ tous voici ma deuxieme question sur ce jolie forum de vbfrance. Un moment HISTORIQUE lol, voici ma question :
Je voudrais declarer une structure en vb.net pour lire
dans un fichier en vb 6 cela donne :
Type MASTRUCT
- Var1(7) as byte
- Var2 as long
- Var3 as integer
- Var4 as string *4
- Var5 as RECT
End Type
alors tout betement j'ai tenté ceci :
Structure MASTRUCT
- Dim Var1(7) as byte '/!\ ahahah ben la ça marche pas !!!
- Dim Var2 as Integer
- Dim Var3 as short
- Dim Var4 as string *4 '/!\ bien vue mais interdit aussi !!!
- Dim Var5 as RECT
End Structure
j'ai tenté aussi ceci :
Structure MASTRUCT
- Dim Var1() as byte
- sub Init()
- - Redim Var1(7)
- End Sub
End Structure
cs_labout
Messages postés1356Date d'inscriptionsamedi 8 décembre 2001StatutMembreDernière intervention23 octobre 20068 31 juil. 2004 à 19:18
labout
Voici un exemple
Private Structure OSVERSIONINFO
Dim OSVSize As Integer
Dim dwVerMajor As Integer
Dim dwVerMinor As Integer
Dim dwBuildNumber As Integer
Dim PlatformID As Integer
Dim szCSDVersion As String
End Structure
Private Structure LUID
Dim dwLowPart As Integer
Dim dwHighPart As Integer
End Structure
Private Structure LUID_AND_ATTRIBUTES
Dim udtLUID As LUID
Dim dwAttributes As Integer
End Structure
Private Structure TOKEN_PRIVILEGES
Dim PrivilegeCount As Integer
Dim laa As LUID_AND_ATTRIBUTES
End Structure
cs_EBArtSoft
Messages postés4525Date d'inscriptiondimanche 29 septembre 2002StatutModérateurDernière intervention22 avril 20199 31 juil. 2004 à 19:25
Merci labout,
mais je crois que tu n'as pas compris la question...
je sait faire une structure de ce type la dessus ya
aucun soucis j'ai egalement des livre vb.net et j'ai consulté
la MSDN mais je n'ai pas trouvé de reponse a cette question :
Comment traduire ceci :
Type MASTRUCT
- Var1(7) as byte
- Var2 as long
- Var3 as integer
- Var4 as string *4
- Var5 as RECT
End Type
sachant que la structure doit etre lut dans un fichier !
le probleme vient de Var1(7) as byte et de Var4 as string * 4
qui n'est pas compatible avec VB.NET.
EXTRAIT :
Marina
I have 2 suggestions:
1) write your own fixed length string class
2) Use class StringBuilder, it has a Capacity property, which you can set.
However, if you append something to it, and the capacity needs to be
increased to accomodate, it will be increased, and you will have to check
for that sort of thing.
Polack77
Messages postés1098Date d'inscriptionmercredi 22 mars 2006StatutMembreDernière intervention22 octobre 20191 24 janv. 2008 à 17:49
Bonjour, à tu trouvé la solution à ton problème ? (oui je sait ça date un peut quand même, mais je cherche moi aussi à lire un fichier de donnée et de chargé tout ça dans des structure, et j'ai réussi, enfin c'est ce que je croyais, avec de l'aide quand même, MERCI NHenry : 2 ici )
Personnellement pour la déclaration d'une chaine de longueur fixe j'ai fait ça (trad auto proposé par VB.NET quand on lui fait ouvrir un fichier VB6) :
8<-----------------------------------------------------------------------
<VBFixedString(LG_TABCRI_NOM), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=LG_TABCRI_NOM)> _
Dim nom() As Char '25 carac
----------------------------------------------------------------------->8
Et ça marche bien quand c'est une structure 'simple' . Mais il me faut la même chose dans une structure 'complexe' (structure contant des structures) et là rien ne vas plus ??? Mes chaine (ou plus exactement mes tableau de char) sont égale à nothing !!!
Du coup j'ai pris un autre chemin :
8<-----------------------------------------------------------------------
Public Sub Initialise()
[...]
For Each Item As S_TAB_UNI In TAB_UNI
Item.Initialise()
Next
[...]
----------------------------------------------------------------------->8
(Avec bien sure une procédure "Initialise" dans mes structure d'un niveau au dessous, ici S_TAB_UNI, fessant un redim de mes tableau de char. Heeeee par contre, une structure contenant des données pouvant être privé, ET des fonctions/procédures, pouvant également être privé ??? Ça ne se nommerais pas une classe ??? Je sait pas moi, mais quand même, il me semble TRÈS fortement que se sont mes cours de débutant ça... J'ai rien dit...). Bà même avec tout cas ça ne marche pas mieux...
Un troisième chemin :
8<-----------------------------------------------------------------------
Public Sub Initialise()
[...]
For Cpt As UInt16 = 0 To NB_EXP_UNI - 1
TAB_UNI(Cpt).Initialise()
Next
----------------------------------------------------------------------->8
Et là... ÇA FONCTIONNE !?!?!? (Déjà pourcois avec un "for" ça fonction alors qu'avec un "foreach" non ?!?!? Bref...)
Forcément je me dit que voila "La victoire de l'homme sur Microbof"... C'étais oublier tout ce que j'ai pue apprendre en utilisant mon Windows 95 à l'époque. (Chez Microbof quand il n'y en à plus il y en à encore, des saleté qui font que tout plante j'entends bien sure)
Grossssse erreur (si vous avez été jeter un coup d'oeil sur le lien plus haut ces codes vont vous dire quelque chose) :
-> Alors déjà 1ér problème la ligne ci dessous me retourne 16 (je présise quand même que dans la structure de plus haut niveau, soit celle qui contien toute les autres structures, se trouve un tableau de char de 20 carac plus 10 structure contant chaqu'une un tableau de char de 26, plus d'autre pitite chose) !!!
8<-----------------------------------------------------------------------
-> Ensuite (non ce n'été pas suffisant...) 2ème problème restant lorsque malgré tout je tente de collé mes données dans ma structure (j'ai mit sa taille en dur dans mon prog, 307 octet exactement) j'ai un message d'erreur à l'execution de la dernierre ligne ci dessous : "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Dot.Net ou l'art de ne plus pouvoir utilisé les structure....
SVP si vous avez une solution AIDEZ MOI !!! JE CRAQUE !!!
PS : Désol pour le pavé mais il falais absolument que je parle de tout ça pour ne pas devenir moi même un produit Microbof (un truc dont on ne comprend pas toujours très bien l'intérêt et en plus qui bug, lol). Grâce à Micobof je vais bientôt pouvoir allé à Psychostar show Amicalement
Pensez "Réponse acceptée"
Polack77
Messages postés1098Date d'inscriptionmercredi 22 mars 2006StatutMembreDernière intervention22 octobre 20191 28 janv. 2008 à 15:25
J'ai fini par trouvé une solution
Attention ça ne fonctionneras pas dans tout les cas, à moins de l'adapter à mort...
La déclaration de chaine de longueur fixe (qui ne fonctionne que dans le cas ci-dessous, tout du moins dans mes test) :
Il faut cette déclaration dans une structure simple (soit dans une structure ne contenant pas d'autre structure)
8<----------------------------------------------------------------------------------------------------
<VBFixedString(LG_DU_TEXT), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=LG_DU_TEXT)> _
Dim Chaine() as Char
Mon objectif été de lire dans un fichier binaire des données écrite avec la méthode put de VB6 et de les chargé dans une structure complexe (j'entends par là contenant d'autre structures)
Méthode :
1) Déclaration de mes structures et variables comme d'habitude
2) Déclaration de nouvelle structure simple basé sur le même schéma que les structure complexe mais sans les sous structures
3) Lecture du fichier en placent les données dans un tableau de byte (mentionnés pour contenir le bon nombre de données)
4) Copie des données grâce à CopyMemory (ou sans doute marchal.copy mais je n'es pas fait de test avec, donc à valider) dans les structures simples.
5) Copie des structure simple dans les structure complexe.
Bon je suis conscient que ça peut paraitre obscure je mes donc un exemple.
8<----------------------------------------------------------------------------------------------------
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As S_Simple, ByRef Source As Byte, ByVal Length As Int16)
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As S_Creation, ByRef Source As Byte, ByVal Length As Int16)
'Déclaration des structures
Private Structure S_Simple
<VBFixedString(C_TailleChaine), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=C_TailleChaine)> _
Public SousChaine() As Char
Public SousValeur As Int16
End Structure
Private Structure S_Objectif
<VBFixedString(C_TailleChaine), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=C_TailleChaine)> _
Public Chaine() As Char
Public Valeur As Int16
Public SousDonnees() As S_Simple
Public Sub Initialise()
ReDim SousDonnees(0 To C_NbSousStrucutre - 1)
End Sub
End Structure
'Structure basé sur le même schema que S_Objectif mais sans le tableau de sous structure
Private Structure S_Creation
<VBFixedString(C_TailleChaine), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=C_TailleChaine)> _
Public Chaine() As Char
Public Valeur As Int16
'Public SousDonnees() As S_Simple
'Public Sub Initialise()
' ReDim SousDonnees(0 To C_NbSousStrucutre - 1)
'End Sub
End Structure
'Fonction de lecture
Public Function LitFichier(ByVal ChemainNomFichier As String, ByRef DonneesFichier() As S_Objectif) As Boolean
Dim Compteur As UInt16 'Compteur utilisé pour remplire le tableau de structure
Dim NombreDeStructure As UInt16 'Varable utilisé pour stocké le nombre de structure à extraire
Dim StreamFichier As System.IO.FileStream 'Streameur fichier (ce qui permet de lire le fichier)
Dim TailleRacine As UInt16
Dim TailleNiveau1 As UInt16
Dim TailleTotalDeLaStructure As UInt16 'Variable utilisé pour stocké la taille de la structure
Dim ConstruitRacine As S_Creation
Dim ConstruitNiveau1() As S_Simple
ReDim ConstruitNiveau1(0 To C_NbSousStrucutre - 1)
TailleRacine = System.Runtime.InteropServices.Marshal.SizeOf(ConstruitRacine)
TailleNiveau1 = System.Runtime.InteropServices.Marshal.SizeOf(ConstruitNiveau1(0))
TailleTotalDeLaStructure = TailleRacine + (TailleNiveau1 * C_NbSousStrucutre) 'Sauvegarde de la taille de la structure
Dim Tampon(0 To TailleTotalDeLaStructure - 1) As Byte 'Le tampon ou les données vont être placé à la lecture (-1 car le tableau commence à 0 et non pas à 1)
Compteur = 0 'Init du compteur si non le complo renvoie un Warning
StreamFichier = New System.IO.FileStream(ChemainNomFichier, System.IO.FileMode.Open, IO.FileAccess.Read) 'L'ouverture du fichier
NombreDeStructure = StreamFichier.Length / TailleTotalDeLaStructure 'Sauvegarde du nombre de structure à priorie présente dans le fichier
ReDim DonneesFichier(0 To NombreDeStructure - 1) 'Création du tableau de structure servant à recevoir les données
While Compteur < NombreDeStructure 'Temps que toute les structure n'ont pas été lut
Try 'Gestion d'erreur
Dim Position As UInt16
StreamFichier.Read(Tampon, 0, TailleTotalDeLaStructure) 'Lit les données et les met dans le tampon
CopyMemory(ConstruitRacine, Tampon(0), TailleRacine) 'Copie des données du tampon dans la structure
For CompteurMaj As UInt16 = 0 To C_NbSousStrucutre - 1
CopyMemory(ConstruitNiveau1(CompteurMaj), Tampon(TailleRacine + TailleNiveau1 * CompteurMaj), TailleNiveau1) 'Copie des données du tampon dans la structure
Next
DonneesFichier(Compteur).Initialise()
DonneesFichier(Compteur).Chaine = ConstruitRacine.Chaine
DonneesFichier(Compteur).Valeur = ConstruitRacine.Valeur
DonneesFichier(Compteur).SousDonnees = ConstruitNiveau1
Compteur = Compteur + 1 'Incrémentation du compteur de boucle
Catch ex As Exception 'Si une erreur se déclenche dans le block Try Catch
StreamFichier.Close() 'Ferme le fichier
Return False 'Retourne faux
Exit Function 'Quite la fonction
End Try 'Fin de la gestion d'erreur
End While 'Fin de la boucle
StreamFichier.Close() 'Ferme le fichier
Return True 'Retourne Vrais (sous entendu tout c'est passé correctement)
End Function
Si la sous structure avais par exemple été entre "Chaine" et "Valeur" il aurais fallut ajouté encore une étape à la lecture.
1) CopyMemory de "Chaine"
2) CopyMemory des sous structure
3) CopyMemory de "Valeur"
(et sans doute une variable qui sauvegarde la position courante dans le tampon)
Voila j'espère avoir été claire. Mais franchement sur ce coup Microbof ne cherche vraiment pas à nous arrangé.
ATTENTION : Je parle ici de lecture d'un fichier binaire qui aurais été crée et/ou encore utilisé par d'autre programme si non il existe des méthode "BinaryFormatter.Serialize" et "BinaryFormatter.Deserialize" simple à utilisé mais qui insère une entête de fichier contenant le type et la version de ce qui à été sauvegarder. Il n'est donc pas possible de lire avec ces méthode si l'entête est absent. De plus le développeur n'a plus complètement les main libre sur la façon dont ses données seront sauvegarder.