Frage zu dllimport & dllexport



  • @rene danke,

    ist das alles, damit 2 dll in wechelseitiger Abhängigkeiten stehen können ?

    //ctrl.dll
    
    #ifdef _MYCTRL_DLLAPI_
        #define MYCTRL_DLLAPI  __declspec( dllexport )
    #else
        #define MYCTRL_DLLAPI  __declspec( dllimport )
    #endif
    
    class MYCTRL_DLLAPI CButtonD : public CButton
    {
      ...
      bool Check();
    
    public:
      afx_msg void OnSetFocus(CWnd* pOldWnd);
    }
    
    //CButton.cpp
    #pragma comment(lib, "dlg.lib")
    #include "CDlgMaskD.h"
    
    void CButtonD::OnSetFocus(CWnd* pOldWnd)
    {
      // hier meine gedanken
      CDlgMaskD* pDlg=new CDlgMaskD()
      ...
      pDlg.Create(...);
      pDlg.ShowWindow(SW_SHOW);
      ...
      delete pDlg;
    }
    
    //dlg.dll
    #pragma comment(lib, "ctrl.lib")
    #include "CButtonD.h" 
    #ifdef _MYANDERE_DLLAPI_
        #define MYANDERE_DLLAPI  __declspec( dllexport )
    #else
        #define MYANDERE_DLLAPI  __declspec( dllimport )
    #endif
    class MYANDERE_DLLAPI CDlgMaskD : public CDialog
    {
      CDlgMaskD() {m_pBtn=NULL;}
    
    private:
      CButtonD* m_pBtn;
    
      bool ask()
      {
        if (m_pBtn)
        {
          if (m_pBtn->Check())
          {
            //joo
          }
        }
      }
    
    }
    

    wenn ja, das geht ja einfach und danke, wenn nein was mache ich falsch.

    volker

    [ Dieser Beitrag wurde am 10.04.2003 um 13:22 Uhr von vdittrich editiert. ]



  • Das pragma hat in der cpp nichts verloren da es heißt linke die lib mit.

    DLL`s sind dazu da um wiederverwendet zu werden.
    Um dem Benutzer der dll das eintragen der lib in seine Konfig zu ersparen macht man das pragma

    #ifdef _DATABASELIB_EXPORTS_
    #define DATABASELIB_API __declspec(dllexport)
    #else
    #define DATABASELIB_API __declspec(dllimport)
    #endif
    
    #ifndef _DATABASELIB_API_NOAUTOLIB_
    #ifdef _DEBUG
    #pragma comment(lib, "databaselibD.lib")
    #else
    #pragma comment(lib, "databaselib.lib")
    #endif
    #endif
    

    So sieht eine meiner Header aus.
    in der stdafx des dllprojectes definiere ich
    #define _DATABASELIB_EXPORTS_

    #define _DATABASELIB_API_NOAUTOLIB_

    Somit wird bei compilieren der dll export angenommen und die lib nicht mitgelinkt.
    Überall wo ich die header einbinde wird import angenommen und die lib gelinkt



  • Original erstellt von Unix-Tom:
    **Das pragma hat in der cpp nichts verloren da es heißt linke die lib mit.

    So sieht eine meiner Header aus.
    in der stdafx des dllprojectes definiere ich
    #define _DATABASELIB_EXPORTS_

    #define _DATABASELIB_API_NOAUTOLIB_

    Somit wird bei compilieren der dll export angenommen und die lib nicht mitgelinkt.
    Überall wo ich die header einbinde wird import angenommen und die lib gelinkt**

    ok, kann dir folgen, mir geht es um
    2 dll in wechelseitiger Abhängigkeiten stehen können

    würde die Implementierung so aussehen ?

    volker



  • 2 dll in wechelseitiger Abhängigkeiten stehen können

    Wo genau ist Dein Denkfehler?

    2 DLLs haben KEINE wechselseitige Abhängigkeit zur Laufzeit, da sie beide in den Speicherbereich der Anwendung gelinkt werden und somit die Anwendung gar nicht mehr mitbekommt, woher der Befehl eigentlich kommt.



  • ich habe ein problem mit __declspec( dllimport),

    und das ich im beiden dll wechselseitig die lib einbinde und ich unsicher bin (hab bis jetzt so was noch nie benutzt) ob ich meine vorstellung so umsetzen läßt.

    mein weg war bis jetzt der function/class ein callback-pointer zu übergeben, der bei bedarf für ein rückruf genutzt werden konnte.

    z.b

    typedef void (*pStateDB)(void* pOb, vStateDB); 
    
    static void StateDB(void* pOb, vStateDB nState)
    {
      ...
    }
    

    es erscheint aber so, das das wirklich so einfach ist. ich werde es heute abend mal in ruhe probieren.

    danke erst mal volker



  • soweit so gut,

    leider noch ein problem.

    im benutze VC 7 und nachdem ich auf Projectmappe bereinigen gehe (alle *.dll, *.lib, *.exp werden gelöscht), bekomme ich logischer weise

    fatal error LNK:1104 Datei "xx.lib" kann nicht geöffnet werden

    was macht man in diesem fall ????



  • Mach 2 Projecte und binden in deine Header das so ein wie beschrieben.
    Somit ist jede LIB/DLL für sich nutzbar.
    Willst du eine dll in der anderen verwenden binde ihren Header ein.
    "wechselseitige Abhängigkeit" kann es nichgt geben da du dich an Programmierrichtlinien halten musst.
    In der Header ein pragma once und die Header wird nicht 2mal eingebunden wenn sie schon da ist.



  • morgen,

    irgendwas mache ich falsch.

    ich habe nur die CGlobalD.sln (separate komponente der dll) geöffnet.

    in der stdafx.h abe ich am ende

    #define MY_CGlobalD_DLLAPI
    
    #pragma comment(lib, "../App/Debug/CMplKernelD.lib")
    

    eingetragen.

    in der header der CIniD.h steht

    #pragma once
    //#include "afxtempl.h"
    #include "CResourceD.h"
    
    typedef void (*pSplit)(void* pParam, const int& nSection, char sKey[], const int& nElem, const size_t sElem[]); 
    
    // CIniD
    #ifdef MY_CGlobalD_DLLAPI
      #define MY_CGlobalD_DLLAPI  __declspec( dllexport )
    #else
      #define MY_CGlobalD_DLLAPI  __declspec( dllimport )
    #endif
    
    class MY_CGlobalD_DLLAPI CIniD
    //class AFX_EXT_CLASS CIniD
    {
    public:
      CIniD(CString sFile);
      ~CIniD(void);
      CIniD(CString sPfad, CString sFile);
      CIniD(eReg& tReg); 
    
      CString GetString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszDefault = "");
      UINT    GetInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, INT nDefault = 0);
      CString GetSection(LPCTSTR lpszSection);
      int GetSection(LPCTSTR lpszSection, CString& sSection, char cSplit = '\n');
      int GetSection(LPCTSTR lpszSection, void* pParam, pSplit pFunc, char cElem = '\0');
    
    private:
      CString m_sFile;
    
    #define MAX_INI_BUFFER  300
    #define MAX_INI_SECTION 0x7fff
    };
    

    und CIniD.cpp

    #include "stdafx.h"
    #include "CIniD.h"
    #include "CRegWndD.h"
    
    // CIniD
    CIniD::CIniD(CString sFile)
    {
      ASSERT(sFile);
      m_sFile=sFile;
    }
    ...//und so weiter
    

    ich denke ich habe alles ordungsgemäß eingebunden.

    ich bekomme aber denoch den fehler
    fatal error LNK1104: Datei'../app/debug/CMplKernelD.lib' kann nicht geöffnet werden.

    eigendlich logisch, sie ist ja auch nicht vorhanden, weil wenn ich die CMplKernel.dll erstellen will erscheint als fehler

    fatal error LNK1104 dDatei'../app/debug/CGlobalD.lib' kann nicht geöffnet werden.

    das meine ich mit abhägigkeit, ich brache die CMplKernelD.lib um CGlobalD.dll zu erstellen und anderesrum die CGlobalD.lib um die CMplKernelD.dll zu erstellen.

    guter rat teuer ??

    volker



  • Das funktioniert jetzt nur noch durch dynamisches Linken.
    Allerdings würde ich Dir eher raten, mal Dein Projektdesign zu überdenken.



  • @rene

    liegt hier ein Designfehler vor (wechelseitige Abhängigkeit der beiden dll's) ??

    habe mir sowas schon gedacht, also in diesem fall keine lösung



  • Wie schon gesagt, mit dynamischem Linken funzt es.



  • @ rene

    ok,

    da die CMplKernelD.dll in mein projekt von anderen dll statisch gelinkt werden und somit im speicher liegt, dürfte es von der performens

    ->LoadLibrary("CMplKernelD.dll")
    ->GetProcAddress(hInst, "GetIniFile")

    keine wesenlichen unterschiede zum zusätlichen dynamischen geben, oder?

    danke nochmal
    [/code]



  • Da das Aufrufen von GetProcAddress nur 1x für jede Funktion erfolgt bzw. erfolgen sollte, dürfte es keinen nennenswerten Performanceverlust geben.



  • @rene ok


Anmelden zum Antworten