Vraag stdcall naam mangling met behulp van extern c en dllexport vs module definities (msvc ++)


Ik probeerde een eenvoudige testfunctie voor een dll te exporteren naar een toepassing (fyi: mIRC) die de aanroepconventie opgeeft als:

int __stdcall test_func(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)

Nu, om dit vanuit de applicatie te bellen, zou ik gebruiken test_func maar ik heb gemerkt dat het vanwege de verminking van de naam niet zo eenvoudig is als ik had gedacht.

Door soortgelijke onderwerpen hier ben ik tot het begrip gekomen dat gebruiken externe "C" in combinatie met __declspec (dllexport) is een equivelante (enigszins) methode voor het verwijderen van mangling naar module-definities (.def). Echter, bij gebruik van de extern / dllexport-methode is mijn functie (als voorbeeld) altijd _test_func @ nummers overwegende dat de .def verwijderd alle mangling zoals vereist voor gebruik met de toepassing die ik nodig om te exporteren naar.

Kan iemand uitleggen waarom dit zo is? Ik ben gewoon nieuwsgierig naar de twee methoden. Bedankt!


14
2017-12-28 23:15


oorsprong


antwoorden:


dllexport / import zijn ontworpen om zelf te worden geladen, niet een oude C-bibliotheek met GetProcAddress. De mangling die je hebt gezien, is wat alle Microsoft-compilers al heel lang doen voor __stdcall-functies. Hoogstwaarschijnlijk verwacht je doel een __cdecl-functie, niet __stdcall, maar als dat niet het geval is, moet je een .def-bestand gebruiken om de naam specifiek te ontcurven.


11
2017-12-28 23:44



extern "C" heeft niets te maken met stdcall: het verklaart alleen dat C ++ naammangling (oftewel type-veilige koppeling; opname van type-informatie in symboolnaam) is uitgeschakeld. U moet het gebruiken, onafhankelijk van het feit of u de convocatie C-bellen of de standaardconventie gebruikt.

In standaardconventie conventie verwijdert de callee de parameters uit de stapel. Om dat veilig te maken, bevat de geëxporteerde naam het aantal bytes dat de opgeruimde persoon uit de stapel zal verwijderen.

Als de toepassing waarnaar u exporteert, dat niet vereist @number achtervoegsel is toegevoegd aan de naam, dit betekent waarschijnlijk dat het C-belconventie verwacht. Dus stop met het declareren van de functie als __stdcall. Wanneer u het als verklaart declspec(dllexport), moet u een onversierde naam in het DLL-bestand krijgen.

In het DEF-bestand kunt u de functie bellen, wat u maar wilt; er wordt geen extra controle uitgevoerd.


12
2017-12-28 23:40