Frage

Im Prozess P / Invoke des Lernens, fragte ich diese vorherige Frage:

  

Wie P / Invoke, wenn Zeiger beteiligt sind

Allerdings verstehe ich nicht ganz die Auswirkungen des in C # P / Invoke mit über einen Wrapper in Managed C ++ Erstellung. Erstellen die gleiche DLL unter Verwendung von P / Invoke in C # auf jeden Fall in einer sauberere Schnittstelle zur Folge, da ich DLLImport auf eingebettete Ressource verwenden könnte, würde aber eine Managed C ++ Wrapper für eine native DLL, wo ich das Marshalling selbst zu tun, hat eine bessere Leistung?

War es hilfreich?

Lösung

C ++ Wrapper schneller sein sollte, haben einen Blick auf diese MSDN-Seite :

  

C ++ Interop verwendet die schnellstmögliche Methode der Daten Serialisieren, während P / Invoke die robusteste Methode verwendet. Das bedeutet, dass C ++ Interop (in einer Art und Weise typisch für C ++) standardmäßig eine optimale Leistung bietet, und der Programmierer ist verantwortlich für die Adressierung Fällen, in denen dieses Verhalten nicht sicher oder geeignet ist.

Also im Grunde der Hauptgrund ist, dass P / Invoke nicht Pinning, Blitten, Fehlerprüfung, während C ++ Interop schiebt nur die Parameter auf dem Stapel und ruft die Funktion.

Ein weiterer Punkt ist, dass C ++ eine mehrere APIs in einem einzigen Aufruf aufrufen können, während P / jeder Parameter durch Adresse übergeben Invoke wird bei jedem Aufruf gepinnt und nicht fixierten, kopiert und kopiert zurück, usw.

Andere Tipps

Möchten Sie eine bessere Leistung? Hängt davon ab, was Sie tun und wie Sie es tun. Im Allgemeinen Ihre Leistungseinbußen mehr wird wahrscheinlich kommen zu tun verwaltet / nicht verwaltete Übergänge und die mehr von diesen können Sie die besser ausgeschnitten. Idealerweise sollten Sie Ihre Anbindung an nicht verwalteten Code sein klobig und nicht gesprächig.

Lassen Sie uns sagen, dass Sie einen nicht verwalteten Code, der eine Sammlung von ein paar tausend Objekte hat. Sie könnten eine API wie diese verwalteten Code aussetzen:

int GetFooCount();
IntPtr GetFoo(int n);
void ReleaseFoo(IntPtr p);

und das ist alles schön und gut, bis Sie mit ihr in C # wie folgt beginnen:

int total = API.GetFooCount();
IntPtr[] objects = new IntPtr[total];
for (int i=0; i < total; i++) {
    objects[i] = GetFoo(i);
}
// and later:
foreach (IntPtr p in objects) { ReleaseFoo(p); }

, die für insgesamt == 1000, wird 4002 verwaltete / nicht verwaltete Übergänge sein. Wenn Sie stattdessen haben diese:

int GetFooCount();
void GetFoos(IntPtr[] arr, int start, int count);
void ReleaseFoos(IntPtr arr, int start, int count);

, dann können Sie die gleiche Arbeit mit 6 Übergänge tun. Welche tun Sie ausführen besser denken?

Natürlich ist die nächste wichtige Frage ist, „ist diese Leistungssteigerung lohnt?“ erinnert so zu messen, zuerst.

Eine Sache, die Sie genauso gut sein sollten sich dessen bewusst ist, dass lustige Dinge zu STL passieren kann, wenn Sie mit Managed C ++ arbeiten. Ich habe einige nicht verwaltete Code-Bibliothek, die STL verwenden geschieht. Meine Erfahrung war, dass, wenn ich jemals eine des STL-Typs in verwaltetem C ++ berühren, alle von ihnen verwalteten Implementierungen wurden. Das Endergebnis war, dass niedrige Niveau Code tat verwaltete / nicht verwaltete Übergänge während Listen iteriert. Huch. Ich löste dies nie die STL-Typen verwalteten C ++ ausgesetzt wird.

Nach unserer Erfahrung ist es viel besser (wenn möglich) C # zu gehen. -> Managed C ++ wrapper-> statische Bibliothek, wenn Sie die Möglichkeit haben, das zu tun

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top