www.mikrocontroller.net

Forum: PC-Programmierung Funktionsnamen beim Import aus DLL


Autor: PZ (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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):
OpenChannel = (int (*)(LPCSTR, UINT8, UINT8, UINT32))GetProcAddress(dllHandle,TEXT("?OpenChannel@@YAHPBDEEI@Z"));

Prozessadresse holen (Windows XP):
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

Autor: der mechatroniker (Gast)
Datum:

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

Autor: Peter (Gast)
Datum:

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

Autor: PZ (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Bartli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: PZ (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: PZ (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.