Hi,
In Fortsetzung von Artificial Minds alter Frage speziell für Visual Studio 2010/2012 x64:
Ich kenne die Adresse eines Kopierk’tors; habe seinen Parameter; und den Ort, an dem ich eine Kopie erzeugen will. Wie rufe ich den Kopierk'tor auf?
Zunächst einmal ist bei der Signatur zu beachten: this als unsichtbarer erster Parameter; Referenz auf das Original als zweiter Parameter. Unter Visual C++ geben außerdem alle Konstruktoren implizit einen Zeiger auf die neue Instanz als Rückgabewert zurück:
typedef void * (CopyConstructor)(void * pThis, void const * pThat);
(Die Referenz als Zeiger zu übergeben ist legitim, da Referenzen in Visual C++’ ABI als Zeiger realisiert werden.)
Den Kopierk'tor aufzurufen wird allerdings den Stack zerschießen, da der Aufruf keiner bekannten Calling Convention folgt:
myCopyCtor(pDestination, pSource);
// Ab hier ist alles kaputt!
Die x86-CRT bietet Quelltext für einen vernünftigen Aufruf:
__declspec(naked) void __stdcall _CallMemberFunction1(
void *pthis, // Value for 'this' pointer
void *pmfn, // Pointer to the member function
void *pthat // Value of 1st parameter (type assumes copy ctor)
) {
__asm {
pop eax // Save return address
pop ecx // Get 'this'
xchg [esp],eax // Get function address, stash return address
jmp eax // jump to the function (function will return to caller of this func)
}
}
(Die 1 am Namensende steht dafür, dass dieser Kopierk'tor einen Parameter gibt. Es gibt scheinbar auch welche mit zweien.)
Leider ist für die x64-CRT kein entsprechender Quelltext mitgeliefert. Was der Compiler erzeugt, ist:
mov rdx,[pSource]
mov rcx,qword ptr [pDestination]
call qword ptr [myCopyCtor]
jmp (Ende)
Aber Inline Assembly gibt es unter Visual C++ x64 nicht.
Und was mache ich jetzt um aufzurufen?
[Visual C++ x64] Konstruktor via Funktionszeiger aufrufen
- Artificial Mind
- Establishment
- Beiträge: 802
- Registriert: 17.12.2007, 17:51
- Wohnort: Aachen
Re: [Visual C++ x64] Konstruktor via Funktionszeiger aufrufe
Kannst du dann nicht einfach eine eigene Datei für die Assembler-Teile anlegen und daraus aufrufen?Krishty hat geschrieben: Aber Inline Assembly gibt es unter Visual C++ x64 nicht.
Also nicht Inline Assembler, sondern ganz normale Assembler-Module.
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [Visual C++ x64] Konstruktor via Funktionszeiger aufrufe
Ich habe ehrlich gesagt Angst vor Prolog, Epilog, und Frame Unwinding. Da die Funktion kein Leaf ist, müsste das ja dann von Hand gemacht werden …
… ich suche gerade, ob ich einen Sprung zu einem Funktionszeiger nicht auch mit Intrinsics hinbekomme.Ich begreife auch nicht, wo der Fehler liegt, weil die Maschinenbefehle des normalen typedef-Aufrufs sehr ähnlich aussehen:
mov rdx,qword ptr [pSource]
mov rcx,qword ptr [pDestination]
call qword ptr [myCopyCtor]
Nachtrag: Das Problem ist, dass der K’tor RCX überschreibt. Hmm.
… ich suche gerade, ob ich einen Sprung zu einem Funktionszeiger nicht auch mit Intrinsics hinbekomme.
mov rdx,qword ptr [pSource]
mov rcx,qword ptr [pDestination]
call qword ptr [myCopyCtor]
Nachtrag: Das Problem ist, dass der K’tor RCX überschreibt. Hmm.
- dot
- Establishment
- Beiträge: 1746
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [Visual C++ x64] Konstruktor via Funktionszeiger aufrufe
Ich komm leider nicht umhin zu fragen: Wofür genau brauchst du das? xD
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [Visual C++ x64] Konstruktor via Funktionszeiger aufrufe
http://zfx.info/viewtopic.php?f=9&t=307&p=36840#p36840
Wird eine User-Type-Ausnahme geworfen und by-value gefangen, muss das Objekt kopiert werden. Dafür gibt mir der Compiler einen Zeiger auf den Kopierk'tor und ein paar Zusatzinformationen wie die Größe des Objekts.
Wird eine User-Type-Ausnahme geworfen und by-value gefangen, muss das Objekt kopiert werden. Dafür gibt mir der Compiler einen Zeiger auf den Kopierk'tor und ein paar Zusatzinformationen wie die Größe des Objekts.
- dot
- Establishment
- Beiträge: 1746
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [Visual C++ x64] Konstruktor via Funktionszeiger aufrufe
Notlösung: Bytecode in Array packen, nach void (*)() casten und aufrufen :>
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [Visual C++ x64] Konstruktor via Funktionszeiger aufrufe
Sieht so aus, als ob ich irgendwo zwischen der 4. und 6. Indirektion einen Zeiger vertauscht hätte. Jedenfalls kann ich auch alles krachen lassen, wenn ich den K'tor nicht aufrufe, sondern einfach memset() auf meinen Zielbereich. Yeah. Ich melde mich zurück, sobald es was Neues gibt.