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 :

Tableau en paramètre d'une fonction d'une dll C++


Sujet :

Delphi

  1. #1
    Membre éclairé Avatar de declencher
    Inscrit en
    Mai 2003
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 441
    Par défaut Tableau en paramètre d'une fonction d'une dll C++
    Bonjour,

    J'aimerai utilisé sous delphi une dll écrite en c++.

    La première fonction ne m'a pas posé de problème car elle ne prennait aucun paramètre. La deuxième à de nombreux paramètres : une chaine de caractère que j'ai écrit en dur pour les tests, 1 float que j'ai remplacé par 1 single, et surtout, un tableau !

    En fait la fonction à un paramètre du type :
    J'ai donc tenté de passer en paramètre un tableau dont j'ai fixé la taille arbitrairement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonTableau : array[0..1000000] of MonType
    MonType est un record que j'ai déclaré car on m'a donné sa structure en C (1 single, et un tableau de 4 char).

    Vous vous en doutez, je plante à l'exécution...

    Je coince, et j'ai l'impression que ce tableau est le seul élément qui me gêne...

    Pour info, la dll est utiliser sans problème par un programme VB.

    Vous avez une idée ?

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 097
    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 097
    Par défaut
    float et single, c'est 4 octets, c'est compatible, OK
    Ce n'est plutôt SAFEARRAY c'est une type particulier, il utilise la Mémoire COM pour s'allouer, il faut utiliser SafeArrayCreate sur un PVarArray\PSafeArray qui s'utilisent globament comme VarArrayCreate sur un Variants

    Attention, une variable locale est limitée, un si grand tableau peut poser des problèmes de taille de pile ! max 1Mo souvent par défaut !
    Utilise un Tableau dynamique et SetLength !
    D'ailleurs pourquoi allouer autant ?
    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

  3. #3
    Membre éclairé Avatar de declencher
    Inscrit en
    Mai 2003
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 441
    Par défaut
    Bonjour,

    J'ai mis un peu de temps à répondre car je souhaitais d'abord me documenter. Et finalement je ne trouve pas de réponse à mes questions.

    Est ce normal qu'en C et en delphi il faille passer par cette structure complexe, alors qu'en VB il suffit de passer en paramètre un tableau d'élément dont je connais la structure ? Et surtout, comment c'est 2 façon d'appeller la fonction peuvent être compatible ? Entre le safearray et le tableau de record que j'ai tenté de créer via Delphi (copiant VB) il y a quand une sacré différence. Je suis un peu perdu là...

    Je vais réduire la taille du tableau, j'avais tenté 20000 et 1000000 car je ne savais pas combien d'élément la fonction allait me renvoyer. L'objectif est de récupérer les points d'un fichier dxf, et je ne connais pas le contenu du fichier de test que j'utilise

  4. #4
    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
    Citation Envoyé par declencher Voir le message
    Bonjour,

    J'ai mis un peu de temps à répondre car je souhaitais d'abord me documenter. Et finalement je ne trouve pas de réponse à mes questions.

    Est ce normal qu'en C et en delphi il faille passer par cette structure complexe, alors qu'en VB il suffit de passer en paramètre un tableau d'élément dont je connais la structure ? Et surtout, comment c'est 2 façon d'appeller la fonction peuvent être compatible ? Entre le safearray et le tableau de record que j'ai tenté de créer via Delphi (copiant VB) il y a quand une sacré différence. Je suis un peu perdu là...

    Je vais réduire la taille du tableau, j'avais tenté 20000 et 1000000 car je ne savais pas combien d'élément la fonction allait me renvoyer. L'objectif est de récupérer les points d'un fichier dxf, et je ne connais pas le contenu du fichier de test que j'utilise
    il est douteux que la taille ne soit pas connue ou qu'il ne soit pas possible de la déterminer.

    ceci dit "**" dans la déclaration indique que c'est un pointeur sur un pointeur (@@ ou ^^ selon le cas sous Delphi).

    il est probable que sous Delphi cela donne un (var p:Pointer), c'est à dire que c'est C++ qui te retourne l'adresse d'un pointeur vers des données. Dans ton cas (var p:PSafeArray);.

    Note que C++ ne fait pas de distinction entre tableaux et pointeurs, un char[] et un char* c'est comme sous Delphi un PChar qui peut être utilisé comme un pointeur sur un char (p^) ou un pointeur sur un tableau de char (p[x]). Sauf qu'en C++ c'est vrai pour tous les types alors que sous Delphi ça ne l'est que pour le PChar.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Membre éclairé Avatar de declencher
    Inscrit en
    Mai 2003
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 441
    Par défaut
    Merci pour ce complément d'info.

    Seul la dll peut déterminer la taille du tableau qu'elle renvoie, car elle seule s'est lire ce format de fichier.

    Après quelques recherches, je commence à comprendre pourquoi sous VB c'est plus simple. Du coup je me concentre sur Delphi, mais je ne trouve que des exemples super complexe.

    Concernant ça j'en étais arrivé à la même conclusion. Il me reste à voir comment déclarer ma variable qui sera en fait un pointeur sur pointeur, et surtout comment exploiter ensuite les données qui auront été insérées par la fonction car je vais devoir mapper les données avec ma structure préalablement déclaré dans delphi...

  6. #6
    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
    ceci dit, tu ne nous donnes aucune info sur le contexte, ni le code VB qui est supposé fonctionner, alors nous ne pouvons faire que des suppositions.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Membre éclairé Avatar de declencher
    Inscrit en
    Mai 2003
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 441
    Par défaut
    Je vais être plus précis mais je n'ai que peu d'info.

    J'ai l'entête de la fonction de la dll qui m'intéresse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DLL_EXPORT long __stdcall LireFichier(SAFEARRAY **MonTableau
    Je connais la déclaration VB de la fonction extraite d'un programme VB qui utilise la dll
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Declare Function LireFichier Lib "DllDXF.dll" (tableau() As MonElement) As Long
    Et je connais la structure de "MonElement" utilisais par le programme VB :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    struct MonElement{
    float X;
    float Y;};
    Vous savez tout

    Naïvement j'ai codé un truc comme ce que je vois en VB : j'ai défini mon record, et j'ai créé un tableau. Mais ça plante quelque soit le bout par lequel je le prends... Un truc m'échappe...

  8. #8
    Membre éclairé Avatar de declencher
    Inscrit en
    Mai 2003
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 441
    Par défaut
    J'ai contacté l'auteur de la dll et il a tester mon exe. ça fonction reçoit bien les paramètres, puis sa fonction s'exécute bien jusqu'au retour à mon appli. C'est là que ça plante avec une erreur concernant la mémoire...

  9. #9
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 097
    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 097
    Par défaut
    Nous allons tous consulter notre Boule de Cristal pour savoir :
    - Comment tu as déclaré LireFichier en Delphi
    - Comment tu procèdes à l'appel de LireFichier (normalement, tu n'as rien à allouer, c'est LireFichier qui le fait avec SafeArrayCreate dans la DLL, mais il faudra tout de même nettoyer le tableau avec SafeArrayDestroy depuis l'EXE sauf si la DLL fourni une méthode de nettoyage)
    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

  10. #10
    Membre éclairé Avatar de declencher
    Inscrit en
    Mai 2003
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 441
    Par défaut
    Pour partir sur plus simple, j'ai changé mes appels dynamique en appel statique. Voici la déclaration de la fonction dans mon code.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      function LireFichier( var tableau: PSafeArray) : longint; cdecl ; external 'DllDXF.dll';
    J'ai tenté d'instancier moi même le SafeArray de cette façon avec 50000 éléments :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    var
      tableau : PSafeArray;
      ArrayBounds : TSafeArrayBound;
    begin
      ArrayBounds.lLbound:= 0;
      ArrayBounds.cElements:= 50000;
      tableau := SafeArrayCreate( VT_VARIANT, 1, ArrayBounds );
      // Appel de la méthode de la dll  
      LireFichier(tableau);
    end;
    Et j'ai tenté de ne pas instancié le SafeArray en me disant que la dll s'en chargeait, comme tu viens de le dire, de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    var
      tableau : PSafeArray;
    begin
      // Appel de la méthode de la dll  
      LireFichier(tableau);
    end;
    Et j'ai essayé ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    var
      tableau : Pointer;
    begin
      // Appel de la méthode de la dll  
      LireFichier(PSafeArray(tableau));
    end;
    J'obtiens toujours le même message avec la même erreur d'accès mémoire...

  11. #11
    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
    Citation Envoyé par declencher Voir le message
    J'ai contacté l'auteur de la dll et il a tester mon exe. ça fonction reçoit bien les paramètres, puis sa fonction s'exécute bien jusqu'au retour à mon appli. C'est là que ça plante avec une erreur concernant la mémoire...
    pourquoi ne lui demandes-tu pas ce qu'il attend comme paramètre ?! c'est tout de même lui le plus à même de te répondre !

    - "in" ou "out"
    - convention d'appel
    - taille des données
    - structure des données
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  12. #12
    Membre éclairé Avatar de declencher
    Inscrit en
    Mai 2003
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 441
    Par défaut
    Je suis en attente de précision demandées cette nuit concernant le safearray.

    Mais comme je n'y connaissais rien au safearray, et que je trouve peux d'information sur le net, je croyais que je l'utilisais mal (ce qui semble être le cas).

    J'attends les réponses de l'auteur de la dll.

  13. #13
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 097
    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 097
    Par défaut
    cdecl ? __stdcall ?
    ce n'est pas la même chose ! remplace cdecl par stdcall !
    Cela doit libérer un truc qu'il ne faut pas, c'est pas bon du tout !

    Je pencherais pour la version :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    var
      tableau : PSafeArray;
    begin
      // Appel de la méthode de la dll  
      LireFichier(tableau);
    end;
    Après tout, tu ne peux pas savoir ce qu'il faut allouer !
    Cela n'a pas de sens d'allouer un tableau de Variant de 50000 elements, ça doit faire facilement 400Ko ça alors que si cela se trouve, tu as un fichier d'une dizaine d'item !
    Le seul intérêt du PSafeArray c'est justement le partage de mémoire COM, allouable d'un côté et libérable de l'autre (ce qui ne se fait pas avec un Pointeur traditionnel qui ne peut être alloué et libéré du même côté)

    un simple "PMonElement" aurait suffit si tu devais toi-même l'allouer avant !

    le SafeArray, c'est aussi lié au VB, je ne connais pas ce langage, semble qu'il utilise un SAFEARRAY implicite, après tout en VB 95% du code c'est des OCX donc du COM ! le VB est le langage pour le Microsoft COM\DCOM ... même si certaines fonctionnalités avancées ne sont disponibles qu'en C++ au prix de code monstreux !
    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

  14. #14
    Membre éclairé Avatar de declencher
    Inscrit en
    Mai 2003
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 441
    Par défaut
    L'auteur de la dll me dit que la dll reçoit bien le safearray, mais que ça plante parce qu'il lui faut un pointeur sur le safearray. Comme je passe déjà un PSafeArray, et vu le header en C, j'en déduis qu'il faut un pointeur sur PSafeArray.

    Il m'a aussi précisé que c'était à moi d'instancier le safearray, puis lui le purge, et le redimensionne au besoin.

    Je me suis rendu compte comme toi que la convention d'appel n'était pas bonne. J'avais vu "cdecl pour les dll C et C++" sur developpez.com, alors j'ai foncé tête baissé comme un âne, mais sans résultat.

    Actuellement, j'ai déclaré un nouveau type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type
      PPSafeArray : ^PSafeArray;
    Puis la déclaration de la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function LireFichier(tableau: PPSafeArray) : longint; stdcall ; external 'DllDXF.dll';
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var
      tableau : PSafeArray;
      pTableau : PPSafeArray;
      ArrayBounds : TSafeArrayBound;
    begin
      ArrayBounds.lLbound:= 0;
      ArrayBounds.cElements:= 10;
      tableau := SafeArrayCreate( VT_VARIANT, 1, ArrayBounds );
      New(pTableau); // J'ai vu que c'était conseillé d'utiliser New/Dispose sur le net...
      pTableau := tableau;
      // Appel de la méthode de la dll  
      LireFichier(tableau);
      Dispose(pTableau);
    end;
    J'obtiens toujours la même erreur concernant la mémoire...

    Je vais finir par y arriver, il faut bien y croire

    Edit : j'avais essayé ta proposition, sans succès. Je confirme que tout est plus facile car implicite en VB. Comme tu peux le voir dans un précédent message, en VB il suffit de déclarer un tableau de "Record"...

  15. #15
    Membre éclairé Avatar de declencher
    Inscrit en
    Mai 2003
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 441
    Par défaut
    Voici ce que je pense être le bon code, avis aux experts, en tout cas pour la première fois il n'y a pas d'exception, et le code retour est positif (négatif en cas d'erreur dans la dll).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type
      PPSafeArray : ^PSafeArray;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function LireFichier(tableau: PPSafeArray) : longint; stdcall ; external 'DllDXF.dll';
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var
      tableau : PSafeArray;
      pTableau : PPSafeArray;
      ArrayBounds : TSafeArrayBound;
    begin
      ArrayBounds.lLbound:= 0;
      ArrayBounds.cElements:= 10;
      tableau := SafeArrayCreate( VT_VARIANT, 1, ArrayBounds );
      pTableau := @tableau;
      // Appel de la méthode de la dll  
      LireFichier(tableau);
    end;
    Je vais contacter l'auteur de la dll pour savoir s'il obtient le même code retour.

    Reste à voir comment exploiter le PPSafeArray qui vient d'être chargé, car finalement c'est ce qui me confirmera si tout est bon fonctionnellement...

  16. #16
    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
    Citation Envoyé par declencher Voir le message
    Voici ce que je pense être le bon code, avis aux experts, en tout cas pour la première fois il n'y a pas d'exception, et le code retour est positif (négatif en cas d'erreur dans la dll).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type
      PPSafeArray : ^PSafeArray;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function LireFichier(tableau: PPSafeArray) : longint; stdcall ; external 'DllDXF.dll';
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var
      tableau : PSafeArray;
      pTableau : PPSafeArray;
      ArrayBounds : TSafeArrayBound;
    begin
      ArrayBounds.lLbound:= 0;
      ArrayBounds.cElements:= 10;
      tableau := SafeArrayCreate( VT_VARIANT, 1, ArrayBounds );
      pTableau := tableau;
      // Appel de la méthode de la dll  
      LireFichier(tableau);
    end;
    Je vais contacter l'auteur de la dll pour savoir s'il obtient le même code retour.

    Reste à voir comment exploiter le PPSafeArray qui vient d'être chargé, car finalement c'est ce qui me confirmera si tout est bon fonctionnellement...
    1) le "new" de ton précédent message n'a rien à faire là, new(), comme getmem() permet d'allouer de la mémoire...ce que tu fais déjà avec le SafeArrayCreate()

    2) tu assignes un PSafeArray à un PPSafeArray, ça fonctionne car ce sont deux pointeurs et du coup Delphi ne râle pas...mais ça ne sert strictement à rien, ça reste exactement le même pointeur. si tu veux un PPSafeArray il faut écrire pTableau := @tableau;.

    en reprend:

    soit une variable Var de type Type et un pointer P : ^Type; (ou PType)

    P := @Var est un PType;
    donc P^ est un Type.

    et donc @P est un PPType.

    La dernière subtilité est le paramètre var qui remplace un "P"

    function toto(i:PType); est strictement équivalent à
    function toto(var i:Type);.

    par contre le paramètre doit être adapté:
    pour la première syntaxe toto(@i); ou
    toto(pi); si pi := @i; évidemment.

    pour la seconde toto(i);.

    et ça reste vrai pour une function (var pi:PType); ou function(ppi: PPType);
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  17. #17
    Membre éclairé Avatar de declencher
    Inscrit en
    Mai 2003
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 441
    Par défaut
    Bien vu

    J'avais oublié le "@", j'ai édité mon message. L'erreur vient du fait que je code sur une machine, et j'écris sur le forum sur une autre, donc pas de copier/coller

  18. #18
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 097
    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 097
    Par défaut
    Je pense que Paul Toth ne te disait pas d'ajouter un @ mais de simplifier ton code !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function LireFichier(var tableau: PSafeArray) : longint; stdcall ; external 'DllDXF.dll';
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var
      tableau : PSafeArray;
      ArrayBounds : TSafeArrayBound;
    begin
      ArrayBounds.lLbound:= 0;
      ArrayBounds.cElements:= 0; // test à zéro, je pense que c'est la DLL, une fois le tableau obtenu, il l'agrandi au besoin
      tableau := SafeArrayCreate(VT_VARIANT, 1, ArrayBounds);
      // Appel de la méthode de la dll  
      LireFichier(tableau);
    end;
    Ensuite, comment transformer un VT_VARIANT en TMonElement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    TMonElement = record
      X: single; // float du c++, 4 octets donc single
      Y: single;
    end;
    Je ne vois pas comment, la DLL peut faire cela ! ce n'est pas un type Automation, donc en terme d'allocation\libération ça ne colle pas !
    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

  19. #19
    Membre éclairé Avatar de declencher
    Inscrit en
    Mai 2003
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 441
    Par défaut
    Exact je peux simplifier. Je pensais avoir déjà testé ça mais non et ça fonctionne. Je vais alléger mon code

    Je ne sais pas comment fait la dll mais ça fonctionne. Voici ce que j'ai du faire de mon côté.
    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
     
    type
      tableStruct : array of MonElement;
    var
      ArrayData : Pointer;
      i : integer;
      sizeArrayData : integer;
     
    begin
      if (SafeArrayAccessData(tableau, ArrayData)=S_OK) then
      begin
        sizeArrayData := retour; // retour est alimenté par LireFichier avec la taille du tableau chargé en mémoire
        for i:=0 to sizeArrayData-1 do
        begin
          // J'écris une valeur du tableau dans un TJvMemo
          JvLog.Lines.add(FloatToStr(tableStruct(ArrayData)[i].X));
        end;
        SafeArrayUnAccessData(tableau);
     
      end;
    Voilà en gros. Pour moi tout fonctionne.

    Merci pour ces échanges.

Discussions similaires

  1. Appel d'une fonction dans une fonction d'une même classe
    Par script73 dans le forum Général Python
    Réponses: 3
    Dernier message: 06/03/2015, 10h18
  2. Réponses: 2
    Dernier message: 24/08/2007, 01h54
  3. Réponses: 4
    Dernier message: 15/08/2007, 22h05
  4. Réponses: 3
    Dernier message: 16/01/2006, 16h02
  5. Réponses: 4
    Dernier message: 17/03/2004, 17h24

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