co naprawdę oznacza __declspec (dllimport)?

Odpowiedzi:

118

__declspecto atrybut specyficzny dla firmy Microsoft, który umożliwia określenie informacji o klasie pamięci.
(Nitpicker's Corner: Jednak wielu innych dostawców kompilatorów - np. GCC - obsługuje teraz to rozszerzenie języka w celu zapewnienia zgodności z zainstalowaną bazą kodu, który został napisany dla kompilatorów firmy Microsoft. Niektórzy nawet zapewniają dodatkowe atrybuty klasy pamięci).

Dwa z tych atrybutów klasy pamięci masowej, które można określić, to dllimporti dllexport. Wskazują one kompilatorowi, że funkcja lub obiekt jest importowany lub eksportowany (odpowiednio) z biblioteki DLL.

Mówiąc dokładniej, definiują interfejs biblioteki DLL dla klienta bez wymagania .DEFpliku definicji modułu ( ). Większość ludzi uważa, że ​​korzystanie z tych rozszerzeń językowych jest znacznie łatwiejsze niż tworzenie plików DEF.

Z oczywistych powodów __declspec(dllimport)i na __declspec(dllexport)ogół są ze sobą sparowane. Służy dllexportdo oznaczania symbolu jako wyeksportowanego z biblioteki DLL i służy dllimportdo importowania tego wyeksportowanego symbolu do innego pliku.

Z tego powodu i ponieważ ten sam plik nagłówkowy jest zwykle używany zarówno podczas kompilowania biblioteki DLL, jak i w kodzie klienta, który zużywa interfejs biblioteki DLL, jest to typowy wzorzec definiowania makra, które jest automatycznie rozpoznawane do odpowiedniego specyfikatora atrybutu w czasie kompilacji. Na przykład:

#if COMPILING_DLL
    #define DLLEXPORT __declspec(dllexport)
#else
    #define DLLEXPORT __declspec(dllimport)
#endif

A następnie zaznaczenie wszystkich symboli, z którymi należy wyeksportować DLLEXPORT.

Przypuszczalnie to właśnie Q_CORE_EXPORTrobi makro, rozwiązując albo Q_DECL_IMPORTalbo Q_DECL_EXPORT.

Cody Gray
źródło
__declspec nie jest poprawnie "specyficzne dla MS" (jest znacznie bardziej "specyficzne dla kompilatora) i niektóre kompilatory używają tej deklaracji także dla wielu platform. Niektóre wartości atrybutów są (dllexport / dllimports są specyficzne dla MS, w rzeczywistości, ponieważ DLL to MS leksykon)
Emilio Garavaglia
9
@Emilio: O ile mi wiadomo, Microsoft wynalazł __declspecnotację jako rozszerzenie języka C ++. Uważam, że GCC teraz to obsługuje, ale to głównie ze względu na kompatybilność z kompilatorami Microsoftu. I nie rozumiem, w jaki sposób „specyficzne dla MS” różni się od „specyficzne dla kompilatora”. Microsoft napisał kompilator C ++ i używa go wiele osób. Pochodzi z Visual Studio.
Cody Grey
8
Microsoft tworzy kompilator. Nazywa się „Microsoft C / C ++ Optimizing Compiler”, cl.exe. Wiele osób błędnie odnosi się do programu Visual Studio, jak do kompilatora, ale jest to IDE. Nie wiem, dlaczego ludzie zastanawiają się, co oznacza określenie „specyficzne dla firmy Microsoft”. Nie oznacza „środowiska MS” (cokolwiek to jest) iz pewnością nie oznacza „Windows”. Tak, inni dostawcy kompilatorów obsługują teraz rozszerzenie w celu zapewnienia zgodności z zainstalowaną bazą kodu napisanego dla kompilatorów firmy Microsoft. Jak powiedziałem wcześniej, o ile wiem, Microsoft wynalazł składnię. O to chodzi tutaj.
Cody Gray
2
@CodyGray: Microsoft sam go wynalazł nie wystarczy. Jednak kiedy Microsoft go wynalazł, żaden standard go nie zawiera, inni implementują go tylko ze względu na kompatybilność i jest używany głównie (jeśli nie wyłącznie) w programach przeznaczonych dla Microsoft Windows razem, co daje bardzo mocny argument nazywanie go „specyficznym dla Microsoft”
celtschk
6
To świetna odpowiedź, szczególnie część dotycząca „ponieważ ten sam plik nagłówkowy jest zwykle używany zarówno podczas kompilowania biblioteki DLL, jak iw kodzie klienta”! Sprawia, że ​​każdy aspekt importu / eksportu jest przejrzysty.
Ela782
30

__declspec(dllimport) to specyfikator klasy pamięci, który informuje kompilator, że funkcja, obiekt lub typ danych są zdefiniowane w zewnętrznej bibliotece DLL.

Funkcja, obiekt lub typ danych są eksportowane z biblioteki DLL z odpowiednim plikiem __declspec(dllexport).

arx
źródło
6
Ok. W końcu, po 2 godzinach czytania, znalazłem najbardziej satysfakcjonujące, zwięzłe i dokładne stwierdzenie tego, czego chcę.
el psy Congroo
1

__declspec(dllexport)informuje kompilator, aby poinformował konsolidator, że te symbole muszą zostać umieszczone w tabeli eksportu (podczas kompilowania .dll). Podczas kompilacji programu, który powiązania z .dll, __declspec(dllimport)informuje kompilator do produkcji absolutną rip-krewny rejestrach pośrednie połączenie pośrednie (który łącznik wypełni postanowienie punktu do tabeli importowej) niż zwykły rip-krewny rejestr-directpośrednia instrukcja wywołania niezdefiniowanej funkcji (która, ponieważ nie może zmodyfikować instrukcji, konsolidator wstawia względny adres pozycji, a następnie tworzy tę pozycję, w której umieszcza względne bezwzględne wywołanie rejestru pośrednie pośrednie wywołanie funkcji wskaźnik funkcji w tabeli importu). To jest optymalizacja rozmiaru kodu i szybkości. To biblioteka importu .lib informuje konsolidatora, które symbole zostaną zaimportowane i jest używana jako przewodnik do tworzenia tabeli importu i tworzenia wszelkich niezbędnych operacji w segmencie .text.

https://docs.microsoft.com/en-us/cpp/build/importing-function-calls-using-declspec-dllimport?view=vs-2019 https://docs.microsoft.com/en-us/cpp / build / importing-data-using-declspec-dllimport? view = vs-2019 https://stackoverflow.com/a/4490536/7194773

Lewis Kelsey
źródło
-2

Oznacza to, że definicja funkcji znajduje się w bibliotece dynamicznej. Odnoszą się do dokumentacji , aby uzyskać więcej informacji i przykładów.

Armen Tsirunyan
źródło