Pointeur en VB.net [Résolu]

Messages postés
417
Date d'inscription
vendredi 22 février 2008
Dernière intervention
7 janvier 2018
- - Dernière réponse : CGSI3
Messages postés
417
Date d'inscription
vendredi 22 février 2008
Dernière intervention
7 janvier 2018
- 13 juin 2010 à 19:13
Bonjour,
je dois utiliser rtlmovememory pour un pointeur sur un tableau de byte,
seulement RtlMoveMemory utilise IntPtr (pointeur sur integer) comment
créer et transformer un pointeur sur tableau de byte en pointeur IntPtr ? Mon code:

Public Declare Sub RtlMoveMemory Lib "kernel32" (ByRef Destination As IntPtr, ByRef Source As IntPtr, ByVal length As Integer)

Dim lBufferIn(lNbByte, .Width, .Height) As Byte
RtlMoveMemory(lBufferIn(1, 1, 1),datTmp.Scan0, lNbByte * .Width * .Height) ==> ne marche pas (conversion de vb6 en VB.net)

J'ai trouvé cela mais je n'y comprend rien ...

'System.Runtime.InteropServices.GCHandle(gch = System.Runtime.InteropServices.GCHandle.Alloc(lBufferIn,System.Runtime.InteropServices.GCHandleType.Pinned))
'IntPtr pTableauDeByte = gch. .AddrOfPinnedObject() //Pointeur vers ton tableau de byte.
'puis quand tu as finis, n'oublis pas de librer avec
'gch.Free()

'Marshal.UnsafeAddrOfPinnedArrayElement(lBufferIn, 0)

Quelqu'un as une idée?
Merci
Afficher la suite 

Votre réponse

16 réponses

Meilleure réponse
Messages postés
1270
Date d'inscription
mardi 11 novembre 2003
Dernière intervention
24 juillet 2013
3
Merci
Salut CSG13

Imports System.Runtime.InteropServices

et non
Imports System.Runtime.InteropServices.Marshal

A utiliser au tout début de ton formulaire

Va voir ma source "Accès direct disques et Partitions" en VB Net et tu auras plein d'exemples de l'utilisation de Marshal.Copy ( feuille Smart.vb en particulier) dont voici l'URL : http://www.vbfrance.com/codes/ACCES-DIRECT-DISQUES-PARTITIONS-VB-NET_46012.aspx

A noter aussi qu'en VB Net les tableaux commencent de préférence à l'indice 0 et non 1


La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.

GRENIER Alain

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 98 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cs_Galain
Messages postés
1270
Date d'inscription
mardi 11 novembre 2003
Dernière intervention
24 juillet 2013
0
Merci
Salut CSG13

RtlMoveMemory travaille en VB NEt avec des pointeurs aussi bien pour la source que la destination
Dans ton exemple datTmp.Scan0 est une variable de quelle type ?

Le principe est le suivant
1) un tableau défini par une variable : lBufferIn()
2) allocation d'une zone mémoire de la même taille
3) un pointeur sur cette zone mémoire
4) on peut utiliser RtlMoveMemory avec ce pointeur
5) on copie la zone mémoire dans le tableau lBufferIn avec Marshal.Copy
6) on libère la zone mémoire

On ne travaille pas sur les variables elles-mêmes mais sur des copies de celles-ci au niveau contenu dans des zones mémoires définies par des pointeurs.

Ne sachant pas quel est le type de la variable datTmp.Scan0 je ne puis te fournir un code
datTmp.Scan0 étant la source il faut aussi lui fournir un pointeur Intptr en mémoire, transférer le contenu de
datTmp.Scan0 dans cette zone mémoire pour enfin pouvoir utiliser RtlMoveMemory

En connaissant le type de variable de datTmp.Scan0 il y a peut-être une façon plus élégante de faire ce transfert sans passer par RtlMoveMemory

La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.

GRENIER Alain
Commenter la réponse de cs_Galain
Messages postés
417
Date d'inscription
vendredi 22 février 2008
Dernière intervention
7 janvier 2018
0
Merci
Merci de ton attention Galain,

Je travail en equipe a fabriquer un moteur 3D avec VB.net & OPENGL

Voici d'ou viens DatTmp

Dim lImage As Bitmap = New Bitmap(NomFichier)
Dim datTmp As Imaging.BitmapData = .LockBits(New Rectangle(0, 0, lImage
.Width, lImage.Height), Imaging.ImageLockMode.ReadOnly, Imaging.PixelFormat.Format32bppArgb)

en fait DatTmp est un tableau 2D de byte
Commenter la réponse de CGSI3
Messages postés
1270
Date d'inscription
mardi 11 novembre 2003
Dernière intervention
24 juillet 2013
0
Merci
Salut CSG13
et Scan0 correspond à quoi ? Car si datTmp est un tableau de bytes Scan0 est quoi comme variable ?
Cela revient-il à transférer le contenu du tableau datTmp dans lBufferIn ?


La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.

GRENIER Alain
Commenter la réponse de cs_Galain
Messages postés
417
Date d'inscription
vendredi 22 février 2008
Dernière intervention
7 janvier 2018
0
Merci
ReBonsoir Galain,
Le but est de créer un canal alpha sur un bitmap pour que opengl puisse gérer la transparence des images
On crée 2 buffers qui représentent les pixels de l'image

Dim lBufferIn(lNbByte, .Width, .Height) As Byte
Dim lBufferOut(4, .Width, .Height) As Byte
On met datTmp (BitmapData) dans un tableau2D() de byte
Puis on traite les points pour créer ce canal Alpha selon pTransparentColor

For lX = 1 To .Width
For ly = 1 To .Height
lBufferOut(1, lX, ly) = lBufferIn(1, lX, ly)
lBufferOut(2, lX, ly) = lBufferIn(2, lX, ly)
lBufferOut(3, lX, ly) = lBufferIn(3, lX, ly)
If RGB(lBufferIn(3, lX, ly), lBufferIn(2, lX, ly), lBufferIn(1, lX, ly)) = pTransparentColor Then
lBufferOut(4, lX, ly) = 0
Else
lBufferOut(4, lX, ly) = 255
End If
Next
Next

lBufferOut étant créé, on doit envoyer son pointeur a gl.gltexImage2D
lBufferOut remplacera datTmp.Scan0 dans la fonction suivante

Call Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, lNbByte, .Width, .Height, 0, lFormat, Gl.GL_UNSIGNED_BYTE, datTmp.Scan0)

J'espere être clair dans mon explication
et surtout si quelquechose a été déja fait je suis preneur ...
Commenter la réponse de CGSI3
Messages postés
417
Date d'inscription
vendredi 22 février 2008
Dernière intervention
7 janvier 2018
0
Merci
d'Apres un code récupéré sur la toile, datTmp.Scan0 représenterai un pointeur sur datTmp (IntPtr)
Commenter la réponse de CGSI3
Messages postés
1270
Date d'inscription
mardi 11 novembre 2003
Dernière intervention
24 juillet 2013
0
Merci
Dans ca cas utilises directement Marshal.copy(source as Intptr,Destination() as byte,StartIndex as integer, Length as integer)
Cela donnerait : Marshal.Copy (datTmp.Scan0,lBufferIn,0,lBufferIn.Length)

La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.

GRENIER Alain
Commenter la réponse de cs_Galain
Messages postés
417
Date d'inscription
vendredi 22 février 2008
Dernière intervention
7 janvier 2018
0
Merci
ReBonsoir et ce sera mon dernier mail du week end,
Pour tout expliquer, et être complet, j'adapte cette procedure qui marchait super bien en VB6 à VB.net seulement les pointeurs sont gérés d'une manière différente...


'---------------------------------------------------------------------------------------
' Charge une texture à partir d'un fichier bitmap
'---------------------------------------------------------------------------------------
Public Function TextureAddFromFile(NomFichier As String, Optional pTransparentColor As Long = -1) As Long
Dim lImage As Object
Dim lTexture As Long
Dim lBitmap As bitmap
Dim lNbByte As Long
Dim lFormat As Long
Dim lBufferOut() As Byte
Dim lBufferIn() As Byte
Dim lX As Long, ly As Long

Set lImage = LoadPicture(pFile) ' Charge l'image
Call GetObjectBmp(lImage, Len(lBitmap), lBitmap) ' Lecture des informations de l'image
' Définition des paramètres fonction de la profondeur de couleur
' Ne sont supportés que les images 24bits et 32bits
Select Case lBitmap.bmBitsPixel
Case 24
lNbByte 3: lFormat GL_BGR_EXT
Case 32
lNbByte 4: lFormat GL_BGRA_EXT
Case Else
Set lImage = Nothing
Exit Function
End Select
glGenTextures 1, lTexture ' Génère une texture
glBindTexture GL_TEXTURE_2D, lTexture ' Définit la texture en texture courante
If pTransparentColor <> -1 Then ' Si une couleur de transparence est spécifiée
' Ajoute un canal alpha si nécessaire, et rend transparent les textels de couleur pTransparentColor
ReDim lBufferOut(1 To 4, 1 To lBitmap.bmWidth, 1 To lBitmap.bmHeight) As Byte
ReDim lBufferIn(1 To lNbByte, 1 To lBitmap.bmWidth, 1 To lBitmap.bmHeight) As Byte
RtlMoveMemory lBufferIn(1, 1, 1), ByVal lBitmap.bmBits, lNbByte * lBitmap.bmWidth * lBitmap.bmHeight
For lX = 1 To lBitmap.bmWidth
For ly = 1 To lBitmap.bmHeight
lBufferOut(1, lX, ly) = lBufferIn(1, lX, ly)
lBufferOut(2, lX, ly) = lBufferIn(2, lX, ly)
lBufferOut(3, lX, ly) = lBufferIn(3, lX, ly)
If RGB(lBufferIn(3, lX, ly), lBufferIn(2, lX, ly), lBufferIn(1, lX, ly)) = pTransparentColor Then
lBufferOut(4, lX, ly) = 0
Else
lBufferOut(4, lX, ly) = 255
End If
Next
Next
' Génère la texture à partir de l'image avec transparence
Call glTexImage2D(GL_TEXTURE_2D, 0, 4, lBitmap.bmWidth, lBitmap.bmHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, _
lBufferOut(1, 1, 1))
Else
' Génère la texture à partir de l'image
Call glTexImage2D(GL_TEXTURE_2D, 0, lNbByte, lBitmap.bmWidth, lBitmap.bmHeight, 0, lFormat, GL_UNSIGNED_BYTE, _
ByVal lBitmap.bmBits)
End If
' Libère l'image
Set lImage = Nothing

glBindTexture GL_TEXTURE_2D, 0
' Renvoie le numéro de la texture créée
TextureAddFromFile = lTexture
End Function
Commenter la réponse de CGSI3
Messages postés
417
Date d'inscription
vendredi 22 février 2008
Dernière intervention
7 janvier 2018
0
Merci
Dim lBufferIn(lNbByte, .Width, .Height) As Byte
Marshal.Copy(datTmp.Scan0, lBufferIn, 0, lBufferIn.Length)

Il me met Marshal.copy non déclaré
Commenter la réponse de CGSI3
Messages postés
1270
Date d'inscription
mardi 11 novembre 2003
Dernière intervention
24 juillet 2013
0
Merci
Mets au tout début de ton formulaire

Imports System.Runtime.InteropServices

La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.

GRENIER Alain
Commenter la réponse de cs_Galain
Messages postés
417
Date d'inscription
vendredi 22 février 2008
Dernière intervention
7 janvier 2018
0
Merci
Ajout de cette ligne en début du module de Form
Imports System.Runtime.InteropServices.Marshal
> Marshal.copy non déclaré
Commenter la réponse de CGSI3
Messages postés
417
Date d'inscription
vendredi 22 février 2008
Dernière intervention
7 janvier 2018
0
Merci
Est ce que tu as déja utilisé cette fonction ?
Elle est bien présente dans l'explorateur mais c'est incroyable que je n'arrive pas a la déclarer Raaaaaaahhhh
Je te remercie néanmoins beaucoup pour ton aide et je continuerai Lundi ...
Bonne nuit et merci surtout pour ton aide précieuse Philippe
Commenter la réponse de CGSI3
Messages postés
417
Date d'inscription
vendredi 22 février 2008
Dernière intervention
7 janvier 2018
0
Merci
Bonjour Galain,
la nuit porte conseil ....
Je viens de déclarer

Imports System.Runtime
en début de module et

InteropServices.Marshal.UnsafeAddrOfPinnedArrayElement(lBufferIn, 0)
dans la fonction et elle se déclare ...
Et seulement de cette manière. Pourquoi? je ne sais pas ....
Elle me met maintenant qu'elle ne peut pas convertir mais je pense réussir avec cela. Je te donnerai une réponse par message lorsque j'aurai fini.

Merci pour ton attention et ton aide.
Si tu t'aventure dans le domaine de la 3D et Opengl, je me ferais un plaisir de t'aider en ce domaine ....
Commenter la réponse de CGSI3
Messages postés
1270
Date d'inscription
mardi 11 novembre 2003
Dernière intervention
24 juillet 2013
0
Merci
Salut CSGI3

Ton Imports en début de module permet d'importer la classe System.Runtime

Mets plutôt en début de module Imports System.Runtime.InteropServices et ensuite dans ton code tu utilises directement les fonctions Marshal.XXXXXX sans être obligé de répéter InteropServices. devant Marshal


La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.

GRENIER Alain
Commenter la réponse de cs_Galain
Messages postés
1270
Date d'inscription
mardi 11 novembre 2003
Dernière intervention
24 juillet 2013
0
Merci
Autre chose

Passe toutes les dimensions de tes tableaux à partir de l'indice 0 et non 1 : en Net on compte toujours à partir de 0


La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.

GRENIER Alain
Commenter la réponse de cs_Galain
Messages postés
417
Date d'inscription
vendredi 22 février 2008
Dernière intervention
7 janvier 2018
0
Merci
http://www.techheadbrothers.com/Articles.aspx/manipulation-images-vb-net-csharp-page-4
Voici sur ce lien ce que j'ai récupéré, je ne l'ai pas encore verifié:

Dim width As Integer = Bitmap.Width
Dim height As Integer = Bitmap.Height
Dim x, y As Integer
Dim bmpData As BitmapData = Bitmap.LockBits(New Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb)
Dim newPixel(width * height - 1) As Integer
Marshal.Copy(bmpData.Scan0, newPixel, 0, newPixel.Length)
Dim temp As Integer
For y = 0 To height - 1
For x = 0 To width - 1
temp = newPixel(width * y + x)
newPixel(width * y + x) = temp And &HFF Or (temp And &HFF00) << 8 Or (temp And &HFF0000) >> 8 Or (temp And &HFF000000)
Next
Next
Marshal.Copy(newPixel, 0, bmpData.Scan0, newPixel.Length)
Bitmap.UnlockBits(bmpData)
Commenter la réponse de CGSI3

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.