Sdílet prostřednictvím


Obecná pravidla a omezení

Specifické pro produkty společnosti Microsoft

  • Pokud deklarujete funkci nebo objekt bez atributu dllimport nebo dllexport, funkce nebo objekt není považován za součást rozhraní knihovny DLL.Proto musí být definice funkce nebo objektu přítomna v tomto modulu nebo v jiném modulu téhož programu.Chcete-li, aby funkce nebo objekt byl součástí rozhraní knihovny DLL, je nutné deklarovat definici funkce nebo objektu v jiném modulu označeném atributem dllexport.Jinak dojde k chybě propojovacího programu.

    Pokud deklarujete funkci nebo objekt s atributem dllexport, jeho definice musí být uvedena v některém modulu téhož programu.Jinak dojde k chybě propojovacího programu.

  • Pokud jeden modul v aplikaci obsahuje deklarace obou atributů dllimport a dllexport pro stejnou funkci nebo objekt, má atribut dllexport přednost před atributem dllimport.Ačkoli bude vygenerováno upozornění kompilátoru.Příklad:

    __declspec( dllimport ) int i;
    __declspec( dllexport ) int i;   // Warning; inconsistent;
                                     // dllexport takes precedence.
    
  • V jazyce C++ lze inicializovat globálně deklarovaný nebo statický místní ukazatel na data nebo s adresou datového objektu deklarovaného s atributem dllimport, který v jazyce C vygeneruje chybu.Kromě toho lze inicializovat ukazatel na statickou místní funkci s adresou funkce deklarované s atributem dllimport.V jazyce C toto přiřazení nastaví ukazatele na adresu převodu importu knihovny DLL (zástupný kód, který předává řízení funkci) namísto adresy funkce.V jazyce C++ nastaví ukazatele na adresu funkce.Příklad:

    __declspec( dllimport ) void func1( void );
    __declspec( dllimport ) int i;
    
    int *pi = &i;                             // Error in C
    static void ( *pf )( void ) = &func1;     // Address of thunk in C,
                                              // function in C++
    
    void func2()
    {
       static int *pi = &i;                  // Error in C
       static void ( *pf )( void ) = &func1; // Address of thunk in C,
                                             // function in C++
    }
    

    Nicméně, protože program, který obsahuje atribut dllexport v deklaraci objektu musí poskytnout definici tohoto objektu jinde v programu, lze inicializovat globální nebo místní ukazatel na statickou funkci adresou funkce s atributem dllexport.Podobně lze inicializovat globální nebo místní ukazatel na statická data adresou datového objektu s atributem dllexport.Následující kód například nevygeneruje v jazyce C nebo C++ chyby:

    __declspec( dllexport ) void func1( void );
    __declspec( dllexport ) int i;
    
    int *pi = &i;                              // Okay
    static void ( *pf )( void ) = &func1;      // Okay
    
    void func2()
    {
        static int *pi = &i;                   // Okay
        static void ( *pf )( void ) = &func1;  // Okay
    }
    
  • Z důvodu změny v chování zavedené v jazyce Visual C++ .NET, aby bylo uplatňování atributu dllexport více konzistentní mezi běžnými třídami a specializacemi šablon tříd, použijete-li atribut dllexport na běžnou třídu, která má základní třídu neoznačenou atributem dllexport, kompilátor vygeneruje upozornění C4275.

    Kompilátor vygeneruje stejné upozornění, pokud je základní třída specializací šablony třídy.Chcete-li tento problém obejít, označte základní třídu atributem dllexport.Problém se specializací šablony třídy je umístění __declspec(dllexport). Nelze označit tuto šablonu třídy.Namísto toho explicitně vytvořte instanci šablony třídy a označte tuto explicitní instanci atributem dllexport.Příklad:

    template class __declspec(dllexport) B<int>;
    class __declspec(dllexport) D : public B<int> {
    // ...
    

    Toto řešení selže, pokud je argument šablony odvozená třída.Příklad:

    class __declspec(dllexport) D : public B<D> {
    // ...
    

    Vzhledem k tomu, že je to společný vzor šablon, kompilátor změní sémantiku atributu dllexport, když je použit na třídu, která má jednu nebo více základních tříd a když je jedna nebo více základních tříd specializací šablony třídy.V tomto případě kompilátor implicitně použije atribut dllexport na specializace šablony třídy.V jazyce Visual C++ .NET může uživatel provést následující kroky a tak potlačit varování:

    class __declspec(dllexport) D : public B<D> {
    // ...
    

Viz také

Referenční dokumentace

dllexport, dllimport