Vra

Ek skryf 'n C / C ++ DLL en wil sekere funksies wat ek gedoen uitvoer voordat die gebruik van 'n .def lêer soos hierdie

LIBRARY "MyLib"
EXPORTS
  Foo
  Bar

met die kode gedefinieer as hierdie, byvoorbeeld:

int Foo(int a);
void Bar(int foo);

Maar wat as ek wil 'n oorlaaide metode van Foo () soos verklaar:

int Foo(int a, int b);

As die def lêer het net die funksie naam en nie die volle prototipe Ek kan nie sien hoe dit die oorlaaide funksies sal hanteer. Het jy net die een inskrywing gebruik en dan spesifiseer watter weergawe jy wil wanneer verby in die behoorlik prototipes funksie wyser om LoadLibrary ()?

oorlaai

Edit: Om duidelik te wees, dit is op Windows met behulp van Visual Studio 2005

Edit: was die metode nie-def (__declspec) as die antwoord ... Ek weet dit nie eintlik die probleem op te los met behulp van def lêers as ek wou, maar dit blyk dat daar waarskynlik geen (amptelike) oplossing met behulp van def lêers. Sal verlaat die vraag oop, maar in geval iemand iets wat ons nie oorlaai funksies en def lêers weet.

Was dit nuttig?

Oplossing

In die kode self, merk die funksies wat jy wil uit te voer met behulp van __declspec (dllexport). Byvoorbeeld:

#define DllExport __declspec(dllexport)

int DllExport  Foo( int a ) {
  // implementation
}
int DllExport Foo( int a, int b ) {
  // implementation
}

As jy dit doen, het jy nie nodig het om 'n lys van die funksies in die .def lêer.

Alternatiewelik kan jy in staat wees om 'n standaard parameter waarde gebruik, soos:

int Foo( int a, int b = -1 )

Dit veronderstel dat daar 'n waarde vir b wat jy kan gebruik om aan te dui dat dit ongebruikte bestaan. As -1 is 'n wetlike waarde vir b, of indien daar nie of mag nie 'n standaard wees, sal dit nie werk nie.

Edit (Adam Haile): gerectificeerd te gebruik __declspec as __dllspec was nie korrek so ek kon dit sien as die amptelike antwoord ... dit was naby genoeg.

Edit (Graeme): Oeps - dankie vir die regstelling van my tikfout

Ander wenke

Funksie oorlading is 'n C ++ funksie wat staatmaak op naam mangling (die kriptiese funksie name in die linker fout boodskappe).

Deur die skryf van die verminkte name in die def lêer, ek kan my toets projek kry om te skakel en uit te voer:

LIBRARY "TestDLL"
EXPORTS
    ?Foo@@YAXH@Z
    ?Foo@@YAXHH@Z

blyk te werk vir

void Foo( int x );
void Foo( int x, int y );

So kopieer die C ++ funksie name van die fout boodskap en skryf dit in jou def lêer. Maar die eintlike vraag is: Hoekom wil jy 'n def lêer gebruik en nie saam met __declspec (dllexport)

?

Die verminkte name nie-draagbare, ek getoets met VC ++ 2008.

Ek het 'n soortgelyke probleem so ek wou post op hierdie so goed.

  1. Gewoonlik gebruik van

    extern "C" __declspec(dllexport) void Foo();
    

    uit te voer 'n funksie naam is fyn. Dit sal gewoonlik die uitvoer van die naam unmangled sonder die behoefte aan 'n .def lêer. Daar is egter 'n paar uitsonderings soos __stdcall funksies en oorlaai funksie name.

  2. As jy verklaar 'n funksie om die gebruik __stdcall konvensie (soos gedoen vir baie API funksies) dan

    extern "C" __declspec(dllexport) void __stdcall Foo();
    

    'n verdwaalde naam uit te voer soos _Foo @ 4. In hierdie geval moet jy dalk uitdruklik karteer die uitvoer naam om 'n interne verminkte naam.

'n. Hoe om 'n unmangled naam uit te voer. In 'n .def lêer voeg

----
EXPORTS
    ; Explicit exports can go here

    Foo
-----

Dit sal probeer om 'n "beste wedstryd" vir 'n interne funksie Foo vind en uit te voer nie. In die geval hierbo waar daar net een cat dit sal die kartering skep

Foo = _Foo @ 4

as kan sien via dumpbin / uitvoere

As jy 'n funksie naam het oorlaai dan moet jy dalk uitdruklik sê watter funksioneer wat jy wil in die .def lêer deur die spesifiseer van 'n verminkte naam met behulp van die entryname [= internalname] sintaksis. Bv.

----
EXPORTS
    ; Explicit exports can go here

    Foo=_Foo@4
-----

B. 'N alternatief vir lêers .def is dat jy name kan uitvoer "in plek" met behulp van 'n #pragma.

#pragma comment(linker, "/export:Foo=_Foo@4")

C. 'N Derde alternatief is om net een weergawe van Foo verklaar as eksterne "C" unmangled uitgevoer word. Sien hier vir meer inligting.

Daar is geen amptelike manier van doen wat jy wil, want die dll koppelvlak is 'n C api.

Die opsteller self gebruik verminkte name as 'n tydelike oplossing, sodat jy naam mangling moet gebruik wanneer jy wil nie te veel verander in jou kode.

Daar is nie 'n taal of weergawe agnostikus manier van uitvoer 'n oorlaaide funksie sedert die mangling konvensie kan verander met elke vrystelling van die samesteller.

Dit is een rede waarom die meeste WinXX funksies snaakse name soos * Ex of * 2.

Systax vir die uitvoer definisie is:

entryname[=internalname] [@ordinal [NONAME]] [PRIVATE] [DATA]

entryname is die funksie of wat jy wil uit te voer veranderlike naam. Dit word vereis. As die naam wat jy uitvoer is anders as die naam in die DLL, spesifiseer die naam van die uitvoer in die DLL met internalname.

Byvoorbeeld, as jou DLL uitvoer 'n funksie, func1 () en jy wil om dit te gebruik as func2 (), sou jy spesifiseer:

EXPORTS
func2=func1

sien Net die verminkte name (dependentie Walker) en spesifiseer jou eie funksies naam.

Bron: http://msdn.microsoft com / af-ons / library / hyx1zcd3 (v = vs.71) Aspx

Edit:. Dit werk vir 'n dinamiese DLLs, waar ons nodig het om GetProcAddress () gebruik om uitdruklik te gaan haal 'n funksie in DLL

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top