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

C++Builder Discussion :

DLL mélange export C et C++ [Système/Fichiers/API]


Sujet :

C++Builder

  1. #1
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut DLL mélange export C et C++
    J'ai une DLL fourni par un tiers (un coréen que j'ai aussi contacté et dont j'attends la réponse)

    DLL écrite en Visual C++
    Il fournisse des projets Visual C++ complet, cela m'a bien aidé d'ailleurs (même si je comprends pas du tout comment il fait pour inclure les fichiers lib et tout ça)

    Evidemment en C++Builder, j'ai du bidouillé les fichier .H pour que cela compile
    La 1ère DLL n'exporte que du C non décoré, ça c'est OK, j'ai déjà fait bcp de dev avec

    La 2nd DLL exporte du C non décoré et C++ décorées, là j'ai un petit problème

    Pour les fonctions C, pas de soucis, j'ai mis extern "C", le linkage passe !
    Sauf pour 4 fonctions C++, il n'indique que le nom de la fonction dans le message d'erreur genre
    [ILINK32 Erreur] Error: 'MaFonction' externe non rÚsolu, rÚfÚrencÚ depuis ...
    Pour les fonctions C++, je me suis dit, faisons pareil avec extern "C++", effectivement, je vois une différence sur le message d'erreur, il énumère les fonctions avec le prototype complet avec la convention d'appel mais sans le type de retour comme
    [ILINK32 Erreur] Error: '__stdcall MaFonction(long)' externe non rÚsolu, rÚfÚrencÚ depuis...
    J'ai généré le fichier lib depuis la DLL avec implib, il est inclu dans le projet
    j'utilise un douzaine de fonction, seule 4 se montrent pénible

    Dependency Walker me donne les noms décorés et j'ai bien la bonne concordance de type !

    Exemple pour MaFonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    // Dans la DLL : ?MaFonction@@YGHPAJ@Z
    // Dans le .H
    BOOL __stdcall MaFonction(LONG *p);
    J'ai donc essayé la méthode de impdef : Using Visual C++ DLLs with C++Builder
    Le ? dans le nom de la fonction lui pose problème :
    Error ...e.def(4): Invalid character in .DEF file
    Pas de bol !

    Je passe donc à Coff2Omf !
    Là, c'est pas mieux, par défaut, il ne génère que quelques fonctions sur une centaine, je joue avec les options, le fichier lib est déjà plus complet mais là aucune fonction n'est lié !

    Mais comment utilisé une DLL MSVC++ en C++Builder !
    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

  2. #2
    Membre expérimenté Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    886
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 886
    Points : 1 526
    Points
    1 526
    Par défaut
    1) Je pense que les fonctions C++ visual sont de toutes façons incompatibles avec Builder. IMPLIB est utile pour appeler les fonctions C, mais pour les fonctions C++, même si on arrive à résoudre les problèmes de décorations, ça plante ensuite à l'exécution.

    2) Si ça peut t'aider, il existe aussi un petit utilitaire pour générer un .lib OMF, un .def ou un .h: http://denis.beru.free.fr/Download/ConvLib.exe (sans garantie)

  3. #3
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut ShaiLeTroll
    je ne suis pas d'accord avec les propos de 10_GOTO_10
    Je pense que les fonctions C++ visual sont de toutes façons incompatibles avec Builder. IMPLIB est utile pour appeler les fonctions C, mais pour les fonctions C++, même si on arrive à résoudre les problèmes de décorations, ça plante ensuite à l'exécution.
    en effet la pluspart des plantées proviennent de l'emploi de mauvaise convention d'appel (thiscall,fastcall.stdcall,cdecl)

    pour ma part dans des dll mixtes(c,c++) j'adopterais la statégie suivante

    • Function C
      importation statique via Implib puis emploi statique de la librairie crée par Implib
      l'emploi dynamique reste également valable, dans ce cas pas besoin de librairie d'importation
    • Function C++
      utilisation dynamique via la paire LoadLibrary et GetProcAdress
      la déclaration des fonctions peut se faire via les functions (undecorate)
      ex :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
       
      typedef long (__cdecl *MYDLLFUNC)(unsigned int *,unsigned int *);
      MYDLLFUNC ImpFuncDLL;
      HINSTANCE hinstDLL= LoadLibrary("H:\\Program Files\\Microsoft Platform SDK\\Bin\\mssnapr.dll");
         ImpFuncDLL= (MYDLLFUNC)GetProcAddress(hinstDLL, "?GetPropSheetCharSizes@@YAJPAI0@Z");
      // et finalement aprés utilisation un petit
      FreeLibrary(hinstDLL);
      un petit bout de code servant à (undecorate) les fonctions c++
      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
       
       
      DWORD OtionMaks=SymSetOptions(SYMOPT_UNDNAME);
        char Buffer[255];
        try
        {
         DWORD BuffLength= UnDecorateSymbolName(
                                                                      Edit1->Text.t_str(),//contient les fonctions décorées commencant par un ?
                                                                      Buffer,
                                                                      255,
                                                                      UNDNAME_COMPLETE);
         if(BuffLength==0)
      	 RaiseLastOSError();
         Edit2->Text=Buffer; // on affiche la fonction (undecorate)
        }
        catch(EOSError&E)
        {
      	  ShowMessage(E.Message);
        }


    cdlt
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Pour le GetProcAddress\LoadLibrary, venant de Delphi, j'y avais pensé (voir mail plus bas que j'ai envoyé à l'auteur), c'est même la seule méthode que je pratiquais jusqu'à présent !
    Je n'aime pas le chargement statique, cela rend dépendant mon programme, bon là ça va, c'est une DLL qui encapsule le tout et mes DLL je ne les charge qu'en dynamique et via une Factory pour un lazy loading !
    Inutile de charger une DLL si on ne l'utilise pas, surtout que la DLL coréenne en charge 8 autres et 12 threads !

    je l'ai d'ailleurs simplifié via des macros, car toutes mes DLL (sorte de drivers) respecte les mêmes interfaces

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define GetProcAddress_GeHardwareProviderInterface(X) (LPFN_GetHardwareProviderInterface)GetProcAddress(X, "GetHardwareProviderInterface")
    typedef IHardwareProvider* (WINAPI *LPFN_GetHardwareProviderInterface)();
    dans ma factory, l'appel est donc très simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
          AnsiString DLLPath = IncludeTrailingPathDelimiter(DLLDirectory) + NewDLLName;
          if (FileExists(DLLPath))
          {
            DLLData->LoadInThreadID = GetCurrentThreadId();
            StrCopy(DLLData->DLLName, DLLPath.c_str());
            DLLData->DLLHandle = _WINDOWS_::LoadLibrary(DLLPath.c_str());
     
            if (DLLData->DLLHandle)
            {
              LPFN_GetHardwareProviderInterface GetHardwareProviderInterface = GetProcAddress_GetHardwareProviderInterface(DLLData->DLLHandle);
              if (GetHardwareProviderInterface)
                DLLData->HardwareProviderIntf = GetHardwareProviderInterface();
    Ensuite, je n'utilise plus jamais la fonction mais l'interface (et sous-interface)


    Peux-t-on mélanger chargement statique et dynamique ?
    En terme d'espace mémoire ?
    Surtout que j'utilise une douzaine de fonction, en fait elle font parti d'un ensemble, la première va me créer un contexte d’exécution, ensuite j'utilise son handle comme paramètre des autres fonctions !
    J'ai un doute sur un mélange !
    Si je dois partir sur un chargement dynamique, je le ferais à 100% pour cette DLL, cela fait un peu de code mais j'ai l'habitude !

    Sinon, j'ai fait le bourrin (j'ai tenté avant de devoir faire un chargement dynamique)
    J'ai bidouillé mon fichier d'alias généré par IMPDEF

    Code def : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    LIBRARY LIB_MACHIN.DLL
     
    EXPORTS
     ; use this type of aliasing
     ; (Borland name) = (Name exported by Visual C++)
        LIB_FonctionBidule =                  ?LIB_FonctionBidule@@YGHJJJP6GXKHK@ZPADK@Z

    le ?LIB_, il n'aime pas, j'ai mis à la place LLIB_
    J'ai généré le fichier LIB avec IMPLIB
    J'ai ouvert ce fichier LIB avec un éditeur Hexa, j'ai remplacé les LLIB_ par ?LIB_, j'ai linké et hop ça fonctionne !

    l'utilisation d'un fichier d'alias ne doit probablement que servir qu'à ça et le comble c'est qu'il ne supporte pas le 1er caractère de décoration VC++ !
    Pourant mon IMPLIB est de 2009 (celui fourni avec XE2), il devrait connaître le ? !
    Étrange, de la mauvaise volonté cher MS et CodeGear ?


    Hello,

    Sorry for my poor english

    I integrate your SDK
    I drive your hardware with "hardware.DLL"
    That is OK ! Excellent Demo and Documentation !

    I need convert Type1 File to Type2 in Real Time
    I use "tool.dll" in "package version ... censure"
    I use fonction LIB_GetHandle, LIB_OpenStream, LIB_SetMode, LIB_Convert ... and 8 another functions
    It's more difficult, i read your Corean documentation with google translate, i not found english doc ?!

    But 30 fonctions are c++ decorated in this tool.DLL
    I use C++Builder 2007 (or Delphi)
    This Microsoft decoration has not supported
    I add extern "c++" or extern "c"

    ?LIB_GetHandle@@YGHPAJ@Z
    ?LIB_ReleaseHandle@@YGHJ@Z
    ?LIB_StopConvert@@YGHJ@Z
    ?LIB_Startonvert@@YGHJPADP6GXJJJPAH0@ZJ@Z

    with extern c
    [ILINK32 Erreur] Error: 'MaFonction' external not resolve...

    with extern c++
    [ILINK32 Erreur] Error: '__stdcall MaFonction(long)' external not resolve...

    How integrated this fonctions with name mangling in C++Builder 2007 ?
    I generated the file lib from the DLL implib (executable of borland, lib from MS is not supported)
    I tried a DEF file with alias IMPDEF but char ? is refused by implib for original name !

    LIBRARY tool.DLL

    EXPORTS
    LIB_GetHandle=?LIB_GetHandle@@YGHPAJ@Z
    LIB_ReleaseHandle=?LIB_ReleaseHandle@@YGHJ@Z
    LIB_StartConvert=?LIB_StartConvert@@YGHJPADP6GXJJJPAH0@ZJ@Z
    LIB_StopConvert=?LIB_StopConvert@@YGHJ@Z

    implib : Error ....def(4): Invalid character in .DEF file
    If i delete ? char, implib make the lib file but wrong name

    How to fix this?

    Monday, I would replace static linking with calls dynamically via LoadLibrary and GetProcAddress, I hope this will solve the problem
    sa réponse franchement pitoyable, même pas capable d'utiliser son correcteur orthographique pour taper un e-mail correct en anglais !
    En même temps, pas de surprise c'est notre offre "premier prix" !
    j'ai été surpris de voir un SDK aussi bien fichu pour un matos si "cheap" !

    would you mind telling me where you are from and more infomationa bout yoru coampny? so i can arrange someone to contat withyou soon ?
    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

  5. #5
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut ShaiLeTroll
    je trouve excellent ta manière générique de charger en mémoire les différents fonctions contenues dans une dll via des interfaces
    mais comment fait-tu avec les différentes conventions d'appels (thiscall,fastcall.stdcall,cdecl) ?
    je ne l'ai pas remanquée dans le bout de code délivré
    cdlt
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    note que j'ai mis WINAPI
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define WINAPI      __stdcall
    La généricité se limite à MES DLL parce que j'ai mis ce système en place !
    C'est un pompage du modèle COM qui lui passe par 4 exports standard,
    DllCanUnloadNow, DllGetClassObject, DllRegisterServer et DllUnregisterServer, moi j'ai juste un équivalent pour DllGetClassObject, je n'ai pas d'enregistrement et je gère manuellement la libération (le COM gère un compteur d'interface qui doit décharger automatiquement la DLL ou l'EXE si l'on a plus d'instance dessus)

    Je n'ai jamais trouvé en COM comment faire pour charger dynamiquement une DLL via son NOM et pas par le GUID pour instancier ses Interfaces sans devoir l'installer !
    C'est ce qui me gène le plus avec le COM, c'est le déploiement certes facile avec RegSvr32, mais on est obligé de créer une classe GUID différente pour chaque DLL et c'est assez pénible de gérer la même interface dans plusieurs TLB (il faut la recopier à chaque fois, c'est très moche)

    En fait, j'ai pour principe de toujours faire une classe d'encapsulation des DLL, que ce soient mes DLL ou des DLL tiers, je ne les utilises jamais directement, ainsi si je change de DLL, je n'ai qu'à refaire le wrapper en espérant pouvoir refournir la même interface !
    Parfois, il est nécessaire d'assouplir la classe d'encaspulation, on peut s'en sortir avec un Pattern Adapter
    D'ailleurs, je pratique souvent le couplage Factory\Registry qui finalement s'apparante à une Patten Strategy

    Mon chargement générique est lié à l'architecture que j'ai mis en place, toutes les DLL "Hardware" que j'ai créé pour piloter différent type de périphérique respecte le même exports, à par le fichier DEF que je dois faire pour chaque projet, la première étape c'est la création d'un fichier contenant ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    EXPORTS
      GetHardwareProviderInterface
      GetHardwareLastError
    Pour l'implémentation de ces deux fonctions, j'inclus une unité toute prête "HardwareAbstractExports.cpp" dont le .H contient ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    extern "C"
    {
      // Exportation non décorée par Extern "C" !
      IHardwareProvider* WINAPI GetHardwareProviderInterface();
      THardwareInterfaceErrorType WINAPI GetHardwareLastError();
    }
    le code étant commun

    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
    IHardwareProvider* WINAPI GetHardwareProviderInterface()
    {
      IHardwareProvider* Result = NULL;
     
      if (CHardwareAbstractDLLExports::FInstance)
        Result = CHardwareAbstractDLLExports::FInstance->GetHardwareProviderInterface();
     
      return Result;
    }
     
    //---------------------------------------------------------------------------
    THardwareInterfaceErrorType WINAPI GetHardwareLastError()
    {
      THardwareInterfaceErrorType Result = shwieIncompleteDLL;
     
      if (CHardwareAbstractDLLExports::FInstance)
        Result = CHardwareAbstractDLLExports::FInstance->GetHardwareLastError();
     
      return Result;
    }
    FInstance est déclaré ainsi !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static CAbstractDLLExports* FInstance;
    et CAbstractDLLExports::GetHardwareProviderInterface utilise en interne une méthode abstrait GetHardwareProviderInstance
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /*abstract*/virtual THardwareAbstractProvider* GetHardwareProviderInstance() = 0;
    IHardwareProvider devient le nouveau point d'entrée, l'API GetHardwareProviderInterface est utilisé une seule fois, maintenant que l'on a l'interface, on a accès toutes les fonctionnalités de la DLL de Hardware !

    Le Main de la DLL est toujours comme ceci
    Note que la variable est du type hérité CBiduleTrucDLLExports qui implémente les méthodes abstraites de CAbstractDLLExports (dont l'Interface Factory)

    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
    21
    22
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
      static CBiduleTrucDLLExports DllExportObject; // mon singleton !!!
     
      switch( reason )
      {
        case DLL_PROCESS_ATTACH :
          DllExportObject.DLLProcessAttach();
        break;
     
        case DLL_THREAD_ATTACH :
        case DLL_THREAD_DETACH :
        break;
     
        case DLL_PROCESS_DETACH :
          DllExportObject.DLLProcessDettach();
     
        break;
      }
     
      return 1;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void CAbstractDLLExports::DLLProcessAttach()
    {
        CAbstractDLLExports::FInstance = this;
    }
     
    void CAbstractDLLExports::DLLProcessDettach()
    {
      CAbstractDLLExports::FInstance = NULL;
    }
    Ainsi dès que l'on entre dans la DLL, j'ai mon point d'entre unique qui existe et peut-être utilisé dans la foulée !

    L'astuce consiste que chaque classe héritée de CAbstractDLLExports implémentée dans chaque DLL va créer son propre IHardwareProvider qui expose tout une série de fonctions et propriétés standards pour identifier un Hardware !

    THardwareAbstractProvider est la classe ancêtre qui implémente une partie commune de IHardwareProvider, certaines méthodes devant être implémentée par un objet hérité par exemple THardwareBiduleTrucProvider ... chaque DLL aura sa propre implémentation dont l'une renvoie la liste des Modèles gérées par la DLL via une IHardwareModelList, effectivement pour des appareils d'une même marque, certains fournissent des protocoles génériques d'autres spécifiques à une gamme d'appareil, il faut donc prévoir l'utilisation de DLL tiers ou de protocoles qui peuvent être différent, l'un par exemple serait purement une DLL, un autre un OCX ou encore même un pilotage en HTTP ou une configuration via la MIB, les fabricants ont une grande imagination !
    Chaque IHardwareModel reçoit une implémentation par un objet hérité d'un THardwareAbstractModel qui se nommerait dans notre cas THardwareBiduleTrucModelBlueSerie et THardwareBiduleTrucModelRedSerie si l'on avait deux modèles
    C'est objet Model fournisse une Factory de THardwareEntity\THardwareAbstractEntity qui serait dans notre cas des THardwareBiduleTrucEntityBlueSerie et THardwareBiduleTrucEntityRedSerie

    Ensuite, le Hardware Entity propose un Purpose qui est une Delphi Interface et s'utilise avec un GUID et Supports !
    Un même Purpose pourrait implémenter plusieurs Interface GUID
    On peut découper les taches d'un périphérique en plusieurs groupes, les taches basiques et communes à tous, les taches avancées que les modèles les moins chez ne fournissent pas et les taches spécifiques pour les modèles les plus performants !

    C'est cette Delphi Interface qui va amener les fonctionnalités spécifiques du Device et là c'est illimité, tout dépend le matériel, cela peut être une Caméra, un Bras mécanique, une Porte...

    D'ailleurs j'évoquais cela dans le sujet TADOConnection + Unresolved external


    EDIT : Pour ma fameuse DLL qui mélange C et C++, j'ai au moins 10 versions différentes, en fait, selon le package, je n'ai pas les même exports, j'ai plusieurs packages (des ZIP) contenant des Démos montrant l'utilisation de DLL !
    Moi, un peu bête, j'ai pris la DLL accompagnant la Démo !
    Mais la même DLL est contenu dans d'autres Packages qui concernent une autre partie du périphérique que j'ai codé il y a presque 6 mois et sur les 100 fonctions seules 3 sont décorées dans cette version mais les 4 fonctions que j'utilise ne le sont plus !
    Du coup, j'ai pris ce package (en plus c'est la dernière release) sans avoir besoin de mettre dans alias !
    J'ignore pourquoi ce fabricant fourni des versions différentes de même DLL !
    Leur SDK est bien fichu mais leur gestion des versions est étrange !

    Faudra que je pense qu'à chaque fois que je récupère une nouvelle version à vérifier leurs exports, ils ont l'air de gérer ça en dilettante !
    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

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 29/03/2008, 19h01
  2. Pb compil dll : "cannot export libName_NULL_THUNK_DATA"
    Par benz41 dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 28/08/2007, 19h10
  3. Création dll pour export vers appli VB6
    Par lio33 dans le forum MFC
    Réponses: 1
    Dernier message: 29/06/2007, 15h20
  4. Réponses: 4
    Dernier message: 07/05/2007, 16h47
  5. Réponses: 10
    Dernier message: 02/11/2005, 11h12

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