Tableau de structures dans de la mémoire non-managé
Kevin.Ory
Messages postés840Date d'inscriptionmercredi 22 octobre 2003StatutMembreDernière intervention 7 janvier 2009
-
23 avril 2008 à 09:31
Kevin.Ory
Messages postés840Date d'inscriptionmercredi 22 octobre 2003StatutMembreDernière intervention 7 janvier 2009
-
23 avril 2008 à 09:50
Bonjour,
Je suis en train de faire un Wrapper de l'API Mixer en VB.NET. Je n'ai pas eu de problèmes particuliers jusqu'à ce que je sois apparement obligé de passer par de la mémoire non managé.
Il s'agit de la fonction 'mixerGetLineControls' qui à une structure MIXERLINECONTROLS comme paramètre. Dans certains cas, on doit créer un tableau de structures MIXERCONTROL et définir le pointeur de la 1ère structure du tableau à l'un des membres de MIXERLINECONTROLS:
"The pmxlc parameter references a list of MIXERCONTROL structures that will receive information on all controls associated with the audio line identified by the dwLineID member of the MIXERLINECONTROLS structure. The cControls member must be initialized to the number of controls associated with the line. ..... The cbmxctrl member must be initialized to the size, in bytes, of a single MIXERCONTROL structure. The pamxctrl member must point to the first MIXERCONTROL structure to be filled."
Dans certains cas, il ne faut pas créer un tableau de MIXERCONTROL, mais une seule structure MIXERCONTROL: "The pamxctrl member must point to a MIXERCONTROL structure to be filled"
Et ça, j'ai réussis à le faire et ça fonctionne:
Dim errorCode As Integer ' Code d'erreur lors de l'appel d'une fonction de l'API
Dim hMixer As IntPtr ' Handle de l'objet Mixer
' Création d'une structure MixerControl pour récupérer les infos d'un control
Dim mixerControl As New MIXERCONTROL
mixerControl.cbStruct = Marshal.SizeOf(mixerControl) ' Taille de la structure
Dim pmem As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(mixerControl)) ' Allocation de mémoire non-managé
' Création d'une strucure MixerLineControls pour l'appel de l'API
Dim mixerLineControls As New MIXERLINECONTROLS
mixerLineControls.cbStruct = Marshal.SizeOf(mixerLineControls) ' Taille de la structure
mixerLineControls.dwLineID = &HFFFF0000 ' ID de la ligne (= sortie WaveOut)
mixerLineControls.dwControl = 1342373889 ' ID du control (= Volume)
mixerLineControls.cControls = 0 ' Doit etre a 0 dans notre cas
mixerLineControls.pamxctrl = pmem ' Structure MixerControl pour le retour des infos
mixerLineControls.cbmxctrl = Marshal.SizeOf(mixerControl) ' Taille de la structure MixerControl
' Récupérer les infos de ce control (Handle du Mixer, structure MixerLineControls, flag (2=
ONEBYTYPE))
errorCode = mixerGetLineControls(hMixer, mixerLineControls, 2)
' Récupérer la structure mixerControl à partir de la mémoire non-managé
mixerControl = CType(Marshal.PtrToStructure(mixerLineControls.pamxctrl, GetType(MIXERCONTROL)), MIXERCONTROL)
Marshal.FreeHGlobal(pmem) ' Libérer la mémoire non-managé
' Fermer le mixer
errorCode = mixerClose(hMixer)
' Afficher les infos de la ligne
Console.WriteLine("Nom : " & mixerControl.szName)
Console.WriteLine("Valeur min : " & mixerControl.lMinimum)
Console.WriteLine("Valeur max : " & mixerControl.lMaximum)
Mais lorsque je dois passer un tableau, rien a faire, je n'y arrive pas et je ne trouve rien qui puisse m'aider.
Ceci ne semble pas fonctionner (Erreur = One or more parameters are invalid)
Dim mixerControls() As MIXERCONTROL
Dim pmem As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(mixerControls))
...
mixerLineControls.pamxctrl = pmem
Quelqu'un aurait-il une sugestion?
A voir également:
Tableau de structures dans de la mémoire non-managé
Kevin.Ory
Messages postés840Date d'inscriptionmercredi 22 octobre 2003StatutMembreDernière intervention 7 janvier 200911 23 avril 2008 à 09:50
J'ai oublié de vous mettre les déclarations, si vous voulez faire tourner le code ça vous facilitera grandement la vie :)
Voici le code (de test) complet:
Imports System.Runtime.InteropServices
Public Class Form1
' Déclarations
Friend Declare Function mixerGetLineControls Lib "winmm.dll" Alias "mixerGetLineControlsA" (ByVal hmxobj As Int32, ByRef pmxlc As MIXERLINECONTROLS, ByVal fdwControls As Int32) As Int32
Friend Declare Function mixerOpen Lib "winmm.dll" (ByRef phmx As Int32, ByVal uMxId As Int32, ByVal dwCallback As Int32, ByVal dwInstance As Int32, ByVal fdwOpen As Int32) As Int32
Friend Declare Function mixerClose Lib "winmm.dll" (ByVal hmx As Int32) As Int32
<StructLayout(LayoutKind.Sequential)> _
Friend Structure MIXERCONTROL
Public cbStruct As Integer
Public dwControlID As Integer
Public dwControlType As Integer
Public fdwControl As Integer
Public cMultipleItems As Integer
<MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst:=16)> Public szShortName As String
<MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst:=64)> Public szName As String
Public lMinimum As Integer
Public lMaximum As Integer
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=11, ArraySubType:=UnmanagedType.AsAny)> Public reserved() As Integer
End Structure
<StructLayout(LayoutKind.Sequential)> _
Friend Structure MIXERLINECONTROLS
Public cbStruct As Integer
Public dwLineID As Integer
Public dwControl As Integer
Public cControls As Integer
Public cbmxctrl As Integer
Public pamxctrl As IntPtr
End Structure
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim errorCode As Integer ' Code d'erreur lors de l'appel d'une fonction externe
Dim hMixer As IntPtr ' Handle de l'objet Mixer
' Création d'une structure MixerControl pour récupérer les infos d'un control
Dim mixerControl As New MIXERCONTROL
mixerControl.cbStruct = Marshal.SizeOf(mixerControl) ' Taille de la structure
Dim pmem As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(mixerControl)) ' Allocation de mémoire non-managé
' Création d'une strucure MixerLineControls pour l'appel de l'API
Dim mixerLineControls As New MIXERLINECONTROLS
mixerLineControls.cbStruct = Marshal.SizeOf(mixerLineControls) ' Taille de la structure
mixerLineControls.dwLineID = &HFFFF0000 ' ID de la ligne (= sortie WaveOut)
mixerLineControls.dwControl = 1342373889 ' ID du control (= Volume)
mixerLineControls.cControls = 0 ' Doit etre a 0
mixerLineControls.pamxctrl = pmem ' Structure MixerControl pour le retour des infos
mixerLineControls.cbmxctrl = Marshal.SizeOf(mixerControl) ' Taille de la structure MixerControl
' Récupérer les infos de ce control
errorCode = mixerGetLineControls(hMixer, mixerLineControls, 2)
' Récupérer la structure mixerControl à partir de la mémoire non-managé
mixerControl = CType(Marshal.PtrToStructure(mixerLineControls.pamxctrl, GetType(MIXERCONTROL)), MIXERCONTROL)
Marshal.FreeHGlobal(pmem) ' Libérer la mémoire non-managé
' Fermer le mixer
errorCode = mixerClose(hMixer)
' Afficher les infos de la ligne
Console.WriteLine("Nom : " & mixerControl.szName)
Console.WriteLine("Valeur min : " & mixerControl.lMinimum)
Console.WriteLine("Valeur max : " & mixerControl.lMaximum)
End Sub
End Class