Hallo,
folgende Deklaration einer Funktion gibt es in einem nativem Prozess:
Ich würde gerne mittels C-Sharp diese Funktion aufrufen. Ich habe den Funktionszeiger dieser Funktion, habe aber Probleme die Parameter für den Delegaten richtig aufzubauen.
Die ersten drei Parameter sind ja lediglich Zeiger zu den Strukturen. Das bedeutet, in einem 32-Bit Prozess, ist die Größe der einzelnen Parameter jeweils auch nur 32 - Bit ( 4 Byte ) groß.
Also muss der Delegat ja auch irgendwie nur die Zeiger zu den System.Numerics.Vector3 - Strukturen als Parameter haben.
So meine Theorie. In der Praxis funktioniert das auch, allerdings musste ich um das Ganze funktional und bequem zu machen eine Wrapper-Funktion schreiben die mittels
erstmal die Vektoren an eine Adresse zu pinnen, diese kann ich dann an die Delegat-Instanz übergeben. Funktioniert, allerdings wenn ich die Funktion öfter pro Sekunde aufrufe, tauchen Fehler auf. AccessViolations, oder sogar sowas hier:
Ich denke also, dass irgendwas immer noch nicht stimmt.
Falls es jemand aus dem Funktionsnamen noch nicht herleiten kann, die Funktion führt einen sog. Raycast zwischen Start - und Endvektor aus und liefert ein Ergebnis ob es eine Kollision gab und wenn ja an welcher Position.
Diese Funktion wird vom Spiel auch öfter pro Sekunde benutzt, also kann es nicht an der Funktion selbst liegen.
Meine Wrapper Funktion sowie der Delegat:
Initialisiert wird der Delegat im Konstruktor:
Die Wrapper Funktion:
Nun meine Frage lautet eigentlich, ob es eine einfachere Methode gibt, die Parameter zu übergeben, ohne so umständlich über
Mein erster alternativer Ansatz war es, die Vektor-Parameter mittels
Der Delegat sah in etwa so aus:
Zwar benutze ich hier für den pVecOut Parameter immer noch einen IntPtr weil ich mir bei dem nicht sicher war ob es funktionieren würde, den hatte ich also immer noch mit einem GCHandle - Dings versorgt.
Allerdings ist das beim Aufruf sofort abgestürzt. Ich dachte mir halt, dass der Parameter Vector3 vPos und vEnd dann eben als Pointer zu solch einer Struktur umgewandelt wird, aber dem ist anscheinend nicht so oder ich habe es noch falsch angewandt.
Gibt es hier jemanden der sich damit besser auskennt?
Danke im Voraus
folgende Deklaration einer Funktion gibt es in einem nativem Prozess:
Ich würde gerne mittels C-Sharp diese Funktion aufrufen. Ich habe den Funktionszeiger dieser Funktion, habe aber Probleme die Parameter für den Delegaten richtig aufzubauen.
Die ersten drei Parameter sind ja lediglich Zeiger zu den Strukturen. Das bedeutet, in einem 32-Bit Prozess, ist die Größe der einzelnen Parameter jeweils auch nur 32 - Bit ( 4 Byte ) groß.
Also muss der Delegat ja auch irgendwie nur die Zeiger zu den System.Numerics.Vector3 - Strukturen als Parameter haben.
So meine Theorie. In der Praxis funktioniert das auch, allerdings musste ich um das Ganze funktional und bequem zu machen eine Wrapper-Funktion schreiben die mittels
GCHandle.Alloc(...)
erstmal die Vektoren an eine Adresse zu pinnen, diese kann ich dann an die Delegat-Instanz übergeben. Funktioniert, allerdings wenn ich die Funktion öfter pro Sekunde aufrufe, tauchen Fehler auf. AccessViolations, oder sogar sowas hier:
Ich denke also, dass irgendwas immer noch nicht stimmt.
Falls es jemand aus dem Funktionsnamen noch nicht herleiten kann, die Funktion führt einen sog. Raycast zwischen Start - und Endvektor aus und liefert ein Ergebnis ob es eine Kollision gab und wenn ja an welcher Position.
Diese Funktion wird vom Spiel auch öfter pro Sekunde benutzt, also kann es nicht an der Funktion selbst liegen.
Meine Wrapper Funktion sowie der Delegat:
Initialisiert wird der Delegat im Konstruktor:
Die Wrapper Funktion:
C#-Quellcode
- public bool IntersectObjLine(out Vector3 vecOut, Vector3 vPos, Vector3 vEnd, bool bSkipTrans = false, bool bWithTerrain = false, bool bWithObject = true)
- {
- if (IntersectObjLineInternal == null)
- throw new NullReferenceException("IntersectObjLineInternal has not been initialized!");
- var outVec = Vector3.Zero;
- var vPosHandle = GCHandle.Alloc(vPos, GCHandleType.Pinned);
- var vEndHandle = GCHandle.Alloc(vEnd, GCHandleType.Pinned);
- var vOutHandle = GCHandle.Alloc(outVec, GCHandleType.Pinned);
- var res = Convert.ToBoolean(IntersectObjLineInternal(Base, vOutHandle.AddrOfPinnedObject(), vPosHandle.AddrOfPinnedObject(), vEndHandle.AddrOfPinnedObject(), Convert.ToInt32(bSkipTrans), Convert.ToInt32(bWithTerrain), Convert.ToInt32(bWithObject)));
- vecOut = Marshal.PtrToStructure<Vector3>(vOutHandle.AddrOfPinnedObject());
- vPosHandle.Free();
- vEndHandle.Free();
- vOutHandle.Free();
- return res;
- }
Nun meine Frage lautet eigentlich, ob es eine einfachere Methode gibt, die Parameter zu übergeben, ohne so umständlich über
GCHandle.Alloc
die Adresse herauszufinden.Mein erster alternativer Ansatz war es, die Vektor-Parameter mittels
[MarshalAs(UnmanagedType.LPStruct)]
zu kennzeichnen.Der Delegat sah in etwa so aus:
Zwar benutze ich hier für den pVecOut Parameter immer noch einen IntPtr weil ich mir bei dem nicht sicher war ob es funktionieren würde, den hatte ich also immer noch mit einem GCHandle - Dings versorgt.
Allerdings ist das beim Aufruf sofort abgestürzt. Ich dachte mir halt, dass der Parameter Vector3 vPos und vEnd dann eben als Pointer zu solch einer Struktur umgewandelt wird, aber dem ist anscheinend nicht so oder ich habe es noch falsch angewandt.
Gibt es hier jemanden der sich damit besser auskennt?
Danke im Voraus