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

 Delphi Discussion :

Problème avec capGetDriverDescriptionA ?


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Par défaut Problème avec capGetDriverDescriptionA ?
    Bonjour,

    Je souhaite utiliser les API de Windows pour récupérer la liste des périphériques de capture disponibles.

    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    function capGetDriverDescriptionA(wDriverIndex:Word; lpszName:PAnsiChar; cbName:Integer; lpszVer:PAnsiChar; cbVer:Integer):Boolean; stdcall; external 'avicap32.dll';
     
    function GetDriverList:TStringList;
    var
         wIndex : Word;
         szDeviceName : PAnsiChar;
         szDeviceVersion : PAnsiChar;
    begin
         FillChar(szDeviceName, 80, 0);
         FillChar(szDeviceVersion, 80, 0);
         Result := TStringList.Create;
         for wIndex:=0 to 9 do
         begin
              if capGetDriverDescriptionA(wIndex, szDeviceName, 80, szDeviceVersion, 80) then
                   Result.Add(szDeviceName + ' ' + szDeviceVersion)
              else
                   Break;
         end;
    end;
    Le problème, c'est que j'ai, à la sortie de ma fonction une erreur :
    access violation at 0x00000000: read of address 0x00000000
    J'ai également essayé avec le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    function GetDriverList:TStrings;
    var
         wIndex : Word;
         szDeviceName : PAnsiChar;
         szDeviceVersion : PAnsiChar;
    begin
         Result := TStringList.Create;
         for wIndex:=0 to 9 do
         begin
              if capGetDriverDescriptionA(wIndex, szDeviceName, 80, szDeviceVersion, 80) then
                   Result.Add(StrPas(szDeviceName) + ' ' + StrPas(szDeviceVersion))
              else
                   Break;
         end;
    end;
    Là, j'ai une erreur :
    Exception 'first chance' à $7687B727. Classe d'exception EAccessViolation avec un message 'Violation d'accès à l'adresse 7689DBEF dans le module 'KERNELBASE.dll'. Ecriture de l'adresse 12E8FEDC'. Processus WebCam.exe (7240)
    Pouvez-vous m'aider à corriger ce problème ?

    Merci,
    ZiP

  2. #2
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    var
         szDeviceName : PAnsiChar;
         szDeviceVersion : PAnsiChar;
    begin
         FillChar(szDeviceName, 80, 0);
         FillChar(szDeviceVersion, 80, 0);
    peux-tu réfléchir deux secondes sur ce code et me dire ce qui ne va pas ?
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    szDeviceName et szDeviceVersion sont initialisés à quelle adresse mémoire ?

    EDIT : Grillé par Paul !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  4. #4
    Membre éprouvé
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Par défaut
    Bonjour Paul et ShaiLeTroll,

    J'ai corrigé mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    function GetDriverList:TStrings;
    var
         wIndex : Word;
         szDeviceName : PAnsiChar;
         szDeviceVersion : PAnsiChar;
    begin
         FillChar(szDeviceName, 80, 0);
         FillChar(szDeviceVersion, 80, 0);
         Result := TStringList.Create;
         for wIndex:=0 to 9 do
         begin
              if capGetDriverDescriptionA(wIndex, szDeviceName, 80, szDeviceVersion, 80) then
                   Result.Add(String(szDeviceName) + ' ' + String(szDeviceVersion))
              else
                   Break;
         end;
    end;
    Mais j'ai toujours cette erreur à la sortie de la fonction :
    access violation at 0x00000000: read of address 0x00000000
    Savez-vous pourquoi ?

    EDIT :
    Je viens de voir qu'à la ligne 14, mes variables szDeviceName et szDeviceVersion sont à nil. Alors qu'elle devrait contenir le nom et la version du périphérique étant donné que capGetDriverDescriptionA retourne true ?

    Je suis un peu perdu avec les AnsiString et WideString, je n'ai pas bien compris la différence qu'il y a entre les deux et quand utiliser l'un ou l'autre...

    Merci,
    ZiP

  5. #5
    Expert confirmé
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Par défaut
    Salut

    Tu n'as manifestement pas réfléchi à la question de Paul ou celle de Shai.
    Le FillChar rempli quoi en fait ? That is the question ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    procedure EnumDrivers(AList: TStrings);
    var
      szName, szVersion: array [0..MAX_PATH] of Char;
      Index: Integer;
    begin
      AList.Clear;
      for Index := 0 to 9 do
      begin
        if capGetDriverDescription(Index, @szName, SizeOf(szName),
          @szVersion, SizeOf(szVersion)) then
          AList.AddObject(szName, Pointer(Index));
      end;
    end;
    @+

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    Allocation Mémoire !
    GetMem\FreeMem !

    Rien ne t'empeche d'utiliser ShortString ou AnsiString[80]
    tu es en Unicode, si je me souviens bien, je connais pas les types de ces versions !

    voir aussi capGetDriverDescriptionW et String (UnicodeString[80] c'est faisable ???)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    ce n'est pas un problème de Wide/Ansi, c'est un problème de POINTEUR

    PAnsiChar est un Pointer, alors comment fais-tu rentrer 80 fois 0 dans un Pointer ?
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  8. #8
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    Pour traduire la subtilité de Paul sur FillChar, rappelons que [Zip] est un débutant (depuis longtemps déjà ! non ?)

    quelle la différence entre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FillChar(szDeviceName, 80, 0);
    -> var X non typé recoit une address mémoire, celle qui contient le Pointeur (4 octets, en fait tu ne devrais même pas forcément d'écrire autant de zéro à cet endroit)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FillChar(szDeviceName^, 80, 0);
    -> var X non typé recoit un Pointeur qui fourni l'adresse mémoire d'un buffer (là évidemement sans GetMem, c'est mort
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ZeroMemory(szDeviceName, 80);
    -> Destination est un Pointeur, je trouve cette fonction plus élégante, en plus son code utilise FillChar et montre la subtilité du var non type !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure ZeroMemory(Destination: Pointer; Length: DWORD);
    begin
      FillChar(Destination^, Length, 0);
    end;
    Paul, ce n'est pas un problème Ansi\Wide, mais comme les solutions alternatives comme celle de Claudius pour laisser Delphi gérer la mémoire commence à être proposer, il faut anticiper ce problème !

    Sinon, comme Claudius "array [0..MAX_PATH] of Char", un grand classique que j'utilise avec GetWindowClass, GetTempPath...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Membre éprouvé
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Par défaut
    Bonjour,

    J'avoue que je suis un peu perdu (même beaucoup) avec les différents types (array [0..MAX_PATH] of Char, PChar, PAnsiChar, PWideChar, etc.) et les différentes fonctions (FillChar, GetMem, FreeMem, ZeroMemory, etc.)...

    J'ai corrigé mon code comme celui de Cl@udius, qui me semble le plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    function GetDriverList:TStrings;
    var
         wIndex : Word;
         szDeviceName : array [0..MAX_PATH] of Char;
         szDeviceVersion : array [0..MAX_PATH] of Char;
    begin
         Result := TStringList.Create;
         for wIndex:=0 to 9 do
         begin
              if capGetDriverDescriptionA(wIndex, @szDeviceName, SizeOf(szDeviceName), @szDeviceVersion, SizeOf(szDeviceVersion)) then
                   Result.Add(String(szDeviceName) + ' ' + String(szDeviceVersion))
              else
                   Break;
         end;
    end;
    Je n'ai pas d'erreur mais capGetDriverDescriptionA renvoie toujours false alors que j'ai une WebCam qui est branchée !

    J'ai donc essayé le code de Cl@udius :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    procedure EnumDrivers(AList: TStrings);
    var
         szName, szVersion: array [0..MAX_PATH] of Char;
         Index: Integer;
    begin
         AList.Clear;
         for Index := 0 to 9 do
         begin
              if capGetDriverDescriptionA(Index, @szName, SizeOf(szName), @szVersion, SizeOf(szVersion)) then AList.AddObject(szName, Pointer(Index));
         end;
    end;
    J'ai juste modifié le capGetDriverDescription en capGetDriverDescriptionA et j'ai le même résultat qu'avec mon code...

    Je ne sais pas si le fait d'être sous Windows 7 peut bloquer le bon fonctionnement de cette API ?

    Ma déclaration est peut-être erronée ?

    Merci pour votre aide,
    ZiP

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. problème avec CapGetDriverDescriptionA Lib "avicap32.dll"
    Par Mario Rousson dans le forum VB.NET
    Réponses: 0
    Dernier message: 18/12/2013, 03h11
  2. VC++ Direct3D8, problème avec LPD3DXFONT et LPD3DTEXTURE8
    Par Magus (Dave) dans le forum DirectX
    Réponses: 3
    Dernier message: 03/08/2002, 11h10
  3. Problème avec le type 'Corba::Any_out'
    Par Steven dans le forum CORBA
    Réponses: 2
    Dernier message: 14/07/2002, 18h48
  4. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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