INFO: _declspec(dllimport) & _declspec(dllexport) in Code gebruiken

Vertaalde artikelen Vertaalde artikelen
Artikel ID: 132044 - Bekijk de producten waarop dit artikel van toepassing is.
Alles uitklappen | Alles samenvouwen

Op deze pagina

Samenvatting

Dit artikel vormt een aanvulling op de informatie die in het volgende artikel in de Microsoft Knowledge Base:
107501 INFO: __export vervangen door __declspec in Visual C++, 32-bits
Dit artikel bespreekt de voordelen en de mechanismen van _declspec(DllImport) en _declspec(dllexport) in uw toepassing.

Meer informatie

De 32-bits editie van Visual C++ gebruikt _declspec(dllimport) en _declspec(dllexport) vervangen door het sleutelwoord __export is eerder gebruikt in 16-bits versies van Visual C++.

U hoeft niet te gebruiken _declspec(dllimport) voor uw code te compileren goed, maar hierdoor kan dus de compiler betere code genereren. De compiler kan zeker bekend betere code genereren of een functie in een DLL of niet bestaat, zodat de compiler kan produceren die codes een niveau van gerealiseerd die normaliter aanwezig zijn in een functie overslaan de aanroep die de grens van een DLL wordt gepasseerd.

Met de juiste.DEF bestand uitvoer sectie _declspec(dllexport) is niet vereist. _declspec(dllexport) is toegevoegd voor een eenvoudige manier om te exporteren functies van een.EXE of.DLL zonder een.DEF-bestand.

De rest van dit artikel biedt een tamelijk Low grondig bespreking van deze problemen.

De Win32-Portable Executable File-indeling is ontworpen om het aantal pagina's die moeten worden gewijzigd om invoer te corrigeren. Hiertoe plaatst alle de importeren van adressen voor elk programma in één plaats het adres importeren Tabel. Hiermee wordt de lader van slechts één of twee pagina's als toegang tot deze invoer.

_Declspec(dllimport) voor functieaanroepen wordt gebruikt

In het volgende codevoorbeeld wordt ervan uitgegaan func1 is een functie die zich bevindt in een DLL-bestand van het.EXE-bestand dat de main() functie bevat.

Zonder _declspec(dllimport) deze code gegeven:
void main(void) {
    func1();
}
				
de compiler genereert de code die er zo uit:
call func1
				
en de linker vertaalt de aanroep naar iets dergelijks:
call 0x4000000         ; The address of 'func1'.
				
Als 'func1' in een ander DLL-bestand bestaat, kan niet de linker dit rechtstreeks oplossen omdat er geen manier om te weten wat het adres van de 'func1' is. In de 16-bits omgevingen, de linker wordt dit adres code toegevoegd aan een lijst in de.EXE dat zou de lader patch tijdens runtime met het juiste adres. In 32-bits omgevingen, de linker genereert een thunk waarvoor het weet de adres. De thunk ziet er zo uit:
   0x40000000:    jmp DWORD PTR __imp_func1
				
__Imp_func1 is hier het adres voor de sleuf van de func1 in het adres importeren tabel van de.EXE-bestand. De adressen worden dus de linker bekend. De Loader alleen bijwerken is het.EXE-bestand importeren tabel tijdens het laden voor alles goed werkt.

Met behulp van _declspec(dllimport) dus beter omdat het beter is als de linker genereert een thunk niet als het niet aan. Thunks maken de grotere code (op RISC-systemen kan zijn verschillende instructies) en de cache prestaties nadelig beïnvloeden. Als u de compiler is de functie in een DLL kan het een indirecte oproep genereren voor u.

Nu deze code:
__declspec(dllimport) void func1(void);

void main(void) {
    func1();
}
				
Deze opdracht genereert:
call DWORD PTR __imp_func1
				
Er is geen thunk en geen jmp instructie, zodat de code kleiner is en sneller.

Anderzijds, voor het aanroepen van functies in een DLL-bestand, hoeft u hebt Gebruik een indirecte oproep. Weet u al een functie adres. Tijd en ruimte vereist zijn voor het laden en opslaan van het adres van de functie voordat een indirecte oproep, zodat een directe aanroep altijd sneller en kleiner. Wilt u alleen __declspec(dllimport) gebruiken bij het aanroepen van functies van DLL-bestand van buiten het DLL-bestand zelf. Gebruik geen __declspec(dllimport) op functies in een DLL-bestand bij het samenstellen van die DLL.

_Declspec(dllexport) gebruiken

__Export Microsoft geïntroduceerd in de compiler van 16-bits versie zodat de de compiler automatisch genereren van namen exporteren en plaats deze in een .LIB-bestand. Dit.LIB-bestand kan vervolgens worden gebruikt als een statische.LIB naar een DLL-bestand koppelen.

Microsoft __declspec(dllexport) blijven deze gemak toegevoegd. De doel is de richtlijn exporteren toevoegen aan het bestand, zodat u niet hoeft een.DEF-bestand.

Dit gebruiksgemak is duidelijkst wanneer bij het exporteren van C++ versierd functienamen. Er is geen standaard specificatie voor naamwijzigingen, zo de naam van een geëxporteerde functie kan tussen compiler versies veranderen. Als u _declspec(dllexport), DLL en afhankelijke compileren.EXE-bestanden alleen naar de rekening voor naamgeving conventie wijzigingen noodzakelijk is.

Veel exporteren richtlijnen zoals rangtelwoorden, NAAMLOOS of PRIVAATRECHTELIJKE gemaakt alleen in een.DEF-bestand en er is geen manier om deze kenmerken opgeven zonder een.DEF-bestand. Echter met behulp van _declspec(dllexport) in met een.DEF-bestand veroorzaakt geen bouwen fouten.

Als een verwijzing zoeken via het Win32-WINBASE.H header-bestand. Het bevat Voorbeelden van de beste __declspec(dllexport) en __declspec(dllimport) gebruik.

Met behulp van _declspec(dllexport) en _declspec(dllimport) van gegevens

Voor de gegevens is met behulp van _declspec(dllimport) een gemak item verwijdert een laag basisserver. Wanneer u gegevens importeert uit een DLL wel hebben via de tabel importeren. De Win32-dagen vóór _declspec(DllImport), die dit betekende moest u niet moet vergeten een extra beveiligingsniveau basisserver toegang tot gegevens geëxporteerd vanuit de DLL:
// project.h
#ifdef _DLL     // If accessing the data from inside the DLL
   ULONG ulDataInDll;

else            // If accessing the data from outside the DLL
   ULONG *ulDataInDll;
#endif
				
U zou vervolgens exporteren van de gegevens in uw.DEF-bestand:
// project.def
LIBRARY project
EXPORTS
    ulDataInDll   CONSTANT
				
en toegang tot buiten het DLL-bestand:
if (*ulDataInDll == 0L) {
   // Do stuff here
}
				
Wanneer u de gegevens markeren als __declspec(dllimport), de compiler automatisch de basisserver code voor u genereert. U hoeft niet meer bang de bovenstaande stappen. Zoals eerder vermeld, geen _declspec(dllimport) gebruiken verklaring over de gegevens die bij het maken van het DLL-bestand. Functies binnen het DLL-bestand de tabel importeren niet gebruikt voor toegang tot het object. Daarom u hebt geen extra beveiligingsniveau basisserver aanwezig.

Om automatisch de gegevens van het DLL-bestand exporteert, gebruikt u deze declaratie:
__declspec(dllexport) ULONG ulDataInDLL;
				

Met een.DEF-bestand

Als u kiest voor __declspec(dllimport) samen met een.DEF-bestand u Wijzig de.DEF-bestand om gegevens te gebruiken in plaats van de constante verminderen de waarschijnlijkheid dat onjuiste code een probleem veroorzaakt:
// project.def
LIBRARY project
EXPORTS
    ulDataInDll   DATA
				
De volgende grafiek ziet u waarom:
Keyword     Emits in the import lib     Exports
CONSTANT    __imp_ulDataInDll           ulDataInDll
            __ulDataInDll

DATA        __imp_ulDataInDll           ulDataInDll
				
De __imp_ versie _declspec (dllimport) en constante lijsten en de naam die in de.LIB DLL-bibliotheek importeren die is gemaakt op toestaan dat expliciete koppelen. Lijsten met _declspec(dllimport) en de gegevens alleen het __imp_ versie van de naam.

Als u een constante gebruikt, kan een van de volgende codeconstructies worden gebruikt toegang tot de ulDataInDll:
__declspec(dllimport) ULONG ulDataInDll; /*prototype*/ 
   if (ulDataInDll == 0L)   /*sample code fragment*/ 
				
- of -
ULONG *ulDataInDll;      /*prototype*/ 
if (*ulDataInDll == 0L)  /*sample code fragment*/ 
				
Echter, als u gegevens in uw.DEF-bestand alleen code is gecompileerd met de volgende definitie kan toegang tot de variabele ulDataInDll:
__declspec(dllimport) ULONG ulDataInDll;
if (ulDataInDll == 0L)   /*sample code fragment*/ 
				
Meer riskante constante is omdat als u extra beveiligingsniveau gebruiken basisserver, kan u mogelijk de Import adrestabel openen verwijzing naar de variabele--niet de variabele zelf. Dit type probleem vaak kunt manifest als een toegangsfout omdat de tabel importeren is momenteel alleen-lezen gemaakt door Microsoft compiler en linkers.

De huidige Visual C++-koppelfunctie waarschuwingsbericht een als u deze constante in ziet de.DEF-bestand voor deze kwestie. De enige echte reden gebruiken CONSTANTE is als u een bestand niet opnieuw kunt compileren waar het header-bestand niet lijst dllimport op prototype van de.

Referenties

De Visual C++ Books Online bieden een aanzienlijke hoeveelheid documentatie op de dllexport en dllimport kenmerken storage class. Dit omvat "De kenmerken dllexport en dllimport" en "met dllimport en dllexport in C++ ' onderwerpen in het hoofdstuk "Microsoft-specifieke parameters" van C++ Language Reference en de onderwerpen 'Symbolen exporteren' in de Hoofdstuk "Dll voor Win32 maken" van het programmeren technieken. Zoek ' Verwante onderwerpen ' voor een uitgebreide lijst Books Online voor 'dllimport' of 'dllexport'.

Zie de volgende artikelen in de Microsoft voor meer informatie. Knowledge Base:
90530 Gegevens exporteren uit een DLL-bestand of een toepassing
107501 INFO: __export vervangen door __declspec in Visual C++, 32-bits

Eigenschappen

Artikel ID: 132044 - Laatste beoordeling: woensdag 11 juli 2012 - Wijziging: 4.0
De informatie in dit artikel is van toepassing op:
  • Microsoft Visual C++ 2.0 Professional Edition
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
Trefwoorden: 
kbcode kbcompiler kbinfo kbmt KB132044 KbMtnl
Automatisch vertaald artikel
BELANGRIJK: Dit artikel is vertaald door de vertaalmachine software van Microsoft in plaats van door een professionele vertaler. Microsoft biedt u professioneel vertaalde artikelen en artikelen vertaald door de vertaalmachine, zodat u toegang heeft tot al onze knowledge base artikelen in uw eigen taal. Artikelen vertaald door de vertaalmachine zijn niet altijd perfect vertaald. Deze artikelen kunnen fouten bevatten in de vocabulaire, zinsopbouw en grammatica en kunnen lijken op hoe een anderstalige de taal spreekt en schrijft. Microsoft is niet verantwoordelijk voor onnauwkeurigheden, fouten en schade ontstaan door een incorrecte vertaling van de content of het gebruik ervan door onze klanten. Microsoft past continue de kwaliteit van de vertaalmachine software aan door deze te updaten.
De Engelstalige versie van dit artikel is de volgende: 132044
Vrijwaring inhoud KB-artikelen over niet langer ondersteunde producten
Dit artikel heeft betrekking op producten waarvoor Microsoft geen ondersteuning meer biedt. Daarom wordt dit artikel alleen in de huidige vorm aangeboden en wordt het niet meer bijgewerkt.

Geef ons feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com