Forum: PC-Programmierung Funktionsnamen beim Import aus DLL


von PZ (Gast)


Lesenswert?

Hallo,

ich entwickle gerade an einer DLL, die sowohl unter Windows XP (VC++ 
2008) als auch Windows CE (EVC++ 4.0) möglichst ohne Codeänderungen 
verwendet werden kann. Soweit klappt das auch, nur eine Kleinigkeit 
gefällt mir noch nicht:
Da die DLL dynamisch eingebunden werden soll, muss das aufrufende 
Programm sich zuerst die Adressen der einzelnen Funktionen aus der Dll 
holen. Dazu verwende ich "GetProcAddress", welches einen String 
erwartet, der den Funktionsnamen enthält (den ich aus der Dll extrahiert 
habe). Hier zwei beispielhafte Aufrufe:

Prozessadresse holen (Windows CE):
1
OpenChannel = (int (*)(LPCSTR, UINT8, UINT8, UINT32))GetProcAddress(dllHandle,TEXT("?OpenChannel@@YAHPBDEEI@Z"));

Prozessadresse holen (Windows XP):
1
OpenChannel = (int (*)(LPCSTR, UINT8, UINT8, UINT32))GetProcAddress(dllHandle,"?OpenChannel@@YGHPBDEEI@Z");

Soweit ich es verstanden habe, dienen die Zeichen nach dem "@" zur 
Kodierung der formalen Parameter der funktion, so dass auch überladene 
Funktionen richtig identifiziert werden können, richtig? In meinem Fall 
allerdings unterschieden sich diese Zeichen geringfügig:

CE: ?OpenChannel@@YAHPBDEEI@Z
XP: ?OpenChannel@@YGHPBDEEI@Z

Da die Funktionen die gleichen Parameter verwenden, wundert mich dieser 
Unterschied, und erschwert die Verwendung der verschiedenen Versionen.

Meine Fragen:
- Warum unterscheidet sich die "Signatur" der Funktionen hier?
- Kann ich dies irgendwie beeinflussen?
- Oder ist es alternativ möglich, bei Funktionen die in der Dll nicht 
überladen sind, den "@-Teil" wegzubekommen?

Vielleicht kann mir da ja jemand auf die Sprünge helfen.

Peter

von der mechatroniker (Gast)


Lesenswert?

Wenn wirklich keine Überladungen vorhanden sind, funktioniert 
GetProcAddress auch wenn du den Namen ohne den @-Teil übergibst.

von Peter (Gast)


Lesenswert?

kann man die schnittstelle nicht als C schnittstelle deklarieren, dann 
gibt es keinen Überladungen und die namen sollten dann nur noch 
"OpenChannel" sein.

von PZ (Gast)


Lesenswert?

> Wenn wirklich keine Überladungen vorhanden sind, funktioniert
> GetProcAddress auch wenn du den Namen ohne den @-Teil übergibst.

Gerade im VC++ 2008 ausprobiert mit "?OpenChannel", "OpenChannel" und 
"?OpenChannel@" --> Kriege ich leider jedes mal null zurück. Aus der 
Dokumentation zu GetProcAddr bin ich leider auch nicht viel schlauer 
geworden.

> kann man die schnittstelle nicht als C schnittstelle deklarieren, dann
> gibt es keinen Überladungen und die namen sollten dann nur noch
> "OpenChannel" sein.

Klingt interessant, verschenkt man da noch weitere C++-Funktionalitäten 
außer der Überladung?

Peter

von Bartli (Gast)


Lesenswert?

Ne, tust du nicht, aber du kannst halt nicht mehr überladen, weil damit 
der Linker zwischen Overloads unterscheiden kann, bäckt der Compiler die 
Signatur mit in den Funktionsnamen.

von Peter (Gast)


Lesenswert?

Die Schnittstelle muss ja bloss C sein, darüber kannst du dann ja 
immernoch objekte übertragen.

wenn du ein Objekt braucht kann man ja auch

object* x = DllFunktionGetObject();
und dann mit

x->Foo();

arbeiten.

DllFunktionGetObject muss ja nicht wissen das es im objekte geht, sie 
gibt einfach eine Zeiger raus.

von PZ (Gast)


Lesenswert?

OK, d.h. ich deklariere die Funktion im Dll-Code als extern "C" und 
schaue mir mal an, was für Funktionsnamen generiert werden.

Ich probier das mal kurz aus, Moment.

Peter

von PZ (Gast)


Lesenswert?

OK, wenn ich es im Headerfile als extern "C" deklariere, bekomme ich als 
Funktionsnamen "_OpenChannel@16". Das scheint mir schon mal 
übersichtlicher.

Danke für eure Hilfe,

Peter

von Peter (Gast)


Lesenswert?

Ich habe gerade mal mit MSVS2003 eine dll erzeugt und als im header

extern "C" __declspec(dllexport) int fndlltest2(int);

angegeben, dann ist in der dll nur der name fndlltest2 ohne @ drin.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.