Udostępnij za pośrednictwem


Zasady ogólne i ograniczenia

Programu Microsoft

  • Jeśli zadeklarować funkcję lub obiekt bez dllimport lub dllexport atrybut, funkcji lub obiektu nie jest uważany za część interfejsu biblioteki DLL.W związku z tym definicja funkcji lub obiekt musi być obecny w tym module lub w inny moduł tego samego programu.Aby funkcja lub obiekt części interfejsu biblioteki DLL, należy zadeklarować definicji funkcji lub obiekt w inny moduł jako dllexport.W przeciwnym wypadku zostanie wygenerowany błąd programu łączącego.

    Jeśli zadeklarować funkcję lub obiekt z dllexport atrybutu, jego definicję muszą pojawiać się w niektórych moduł tego samego programu.W przeciwnym wypadku zostanie wygenerowany błąd programu łączącego.

  • Jeśli pojedynczy moduł w programie zawiera zarówno dllimport i dllexport deklaracje dla tej samej funkcji lub obiekt, dllexport atrybutu ma pierwszeństwo przed dllimport atrybut.Jednakże jest generowane ostrzeżenie kompilatora.Na przykład:

    __declspec( dllimport ) int i;
    __declspec( dllexport ) int i;   // Warning; inconsistent;
                                     // dllexport takes precedence.
    
  • W języku C++ można zainicjować wskaźnik globalnie zadeklarowanych lub statycznych danych lokalnych lub z adresem obiektu danych, zadeklarowanych z dllimport atrybut, który generuje błąd w C.Ponadto można zainicjować wskaźnik statyczne funkcja lokalnym o adresie funkcja zadeklarowana z dllimport atrybut.C takie przypisanie ustawia wskaźnik na adres thunk importu biblioteki DLL (Kod szczątkowy przenoszący kontrolę do funkcji) zamiast adresu funkcji.W języku C++ ustawia wskaźnik adresu funkcji.Na przykład:

    __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++
    }
    

    Jednakże ponieważ program obejmuje dllexport atrybutu w deklaracji obiektu musi dostarczyć definicji dla tego obiektu, gdzieś w programie, można zainicjować wskaźnik funkcji statycznej globalny lub lokalny adres dllexport funkcji.Podobnie, można zainicjować wskaźnik globalny lub lokalny danych statycznych z adresem dllexport obiektu danych.Na przykład poniższy kod nie generować błędy w c lub C++:

    __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 powodu zmiany w zachowaniu wprowadzić w programie Visual C++.NET do złożenia wniosku o dllexport bardziej spójne pomiędzy zwykłych klas i specjalizacji szablony klasy, jeśli zastosujesz dllexport do zwykłej klasy, zawierający klasy podstawowej, która nie jest oznaczony jako dllexport, kompilator wygeneruje C4275.

    Kompilator generuje ostrzeżenie w tym samym, jeśli klasa podstawowa jest specjalizacji szablonu klasy.Aby obejść ten problem, należy oznaczyć klasa bazowa z dllexport.Problem z specjalizacji szablonu klasy jest miejsce opcję __declspec(dllexport); nie możesz oznaczyć szablonu klasy.Zamiast tego należy jawnie wystąpienia szablonu klasy i znak ten jawnego wystąpienia z dllexport.Na przykład:

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

    To obejście nie powiedzie się, jeśli argument szablonu jest klasa wynikających.Na przykład:

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

    Ponieważ jest to wspólnego wzorca z szablonami, kompilator zmianie semantykę dllexport , gdy jest ono stosowane do klasy, która ma jeden lub więcej klasy base i gdy jedno lub więcej podstawowych klas jest specjalizacji szablonu klasy.W tym przypadku kompilator niejawnie dotyczy dllexport do specjalizacji klasy szablonów.W programie Visual C++.NET, użytkownik może wykonać następujące czynności i nie otrzymać ostrzeżenie:

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

Zobacz też

Informacje

dllexport, dllimport