IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Appel de code non-managé


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut Appel de code non-managé
    Bonjour,

    Dans le cadre de la migration d'une appli VB6 en VB.NET, je me retrouve confronté au problème d'appeler du code non-managé (de winspool.drv) depuis mon code VB.NET. Je précise que je maîtrise plutôt bien C++, mais que je suis une bille en VB, avec ou sans .NET.

    J'ai donc déclaré la méthode en question :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Private Declare Function EnumMonitors Lib "winspool.drv" Alias "EnumMonitorsA" (ByVal pName As String, ByVal Level As System.UInt32, ByRef pMonitors As MONITOR_INFO_1(), ByVal cdBuf As System.UInt32, ByRef pcbNeeded As System.UInt32, ByRef pcReturned As System.UInt32) As System.Int32
    J'ai bien évidemment défini la structure MONITOR_INFO_1 pour correspondre à ce qu'attent la fonction EnumMonitorsA.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Structure MONITOR_INFO_1
            Dim pName As String
    End Structure
    Et, lors de l'appel, mon premier appel à EnumMonitors, avec Nothing sur le troisième paramètre, se passe bien. Le deuxième, avec une array de MONITOR_INFO_1 (de la bonne taille), se passe très mal en revanche, puisqu'il fait planter le CLR.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Dim tmp As MONITOR_INFO_1 = New MONITOR_INFO_1
    Dim size As Integer = System.Runtime.InteropServices.Marshal.SizeOf(tmp.GetType())
    Dim mi1(sizeNeeded / size) As MONITOR_INFO_1 'sizeNeeded a été renvoyé par le premier appel à EnumMonitorsA
    If EnumMonitors(vbNullString, 1, mi1, pcbNeeded, pcbNeeded, pcReturned) Then 'ici ça plante avec un System.ExecutionEngineException
    Je passe mes paramètres correctement si j'en crois MSDN, et ma structure a la bonne taille (4).

    Donc, qu'est-ce que j'ai fait de mal ?

  2. #2
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut
    Je pense qu'il faut que tu rajoutes un attribut "MarshalAs(UnmanagedType.LPTStr)" au pName de ta Struct pour indiquer que c'est un TChar*

  3. #3
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Finalement, je m'en suis sorti comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Private Declare Function EnumMonitors Lib "winspool.drv" Alias "EnumMonitorsA" (ByVal pName As String, ByVal Level As System.UInt32, ByVal pMonitors As IntPtr, ByVal cdBuf As System.UInt32, ByRef pcbNeeded As System.UInt32, ByRef pcReturned As System.UInt32) As System.Int32
     
    Dim monitors As IntPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(pcbNeeded)
     
    If EnumMonitors(vbNullString, 1, monitors, pcbNeeded, pcbNeeded, pcReturned) Then
    For i = 0 To (pcReturned - 1)
                        mi1 = System.Runtime.InteropServices.Marshal.PtrToStructure(New IntPtr(monitors.ToInt64() + i * size), GetType(MONITOR_INFO_1))
    Ca a l'avantage que je comprends bien ce qui se passe, même si ça me semble bien compliqué pour si peu... (impossible de faire fonctionner ce qui est décrit dans http://msdn.microsoft.com/en-us/library/hk9wyw21.aspx)

    Je ne le note pas résolu tout de suite, car si quelqu'un a une solution un peu plus simple, je suis preneur.

Discussions similaires

  1. Réponses: 0
    Dernier message: 13/03/2013, 11h39
  2. Réponses: 12
    Dernier message: 23/05/2007, 21h40
  3. [C++] Appel via paramètres non managés
    Par JulienDuSud dans le forum Framework .NET
    Réponses: 4
    Dernier message: 28/12/2005, 10h42
  4. code non managé avec interface managée ...
    Par izbad dans le forum MFC
    Réponses: 6
    Dernier message: 19/12/2005, 16h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo