Wie kann ich einen fstream oder ein Äquivalent von C # über CLI an eine nicht verwaltete C ++ - DLL übergeben?
Grobe Anwendungsgliederung:
Ich speichere gerade die Binärdatei auf Festplatte und übergebe den Pfad an den CLI-Wrapper, wo sie als fstream geöffnet wird. Dies ist für Testzwecke geeignet, funktioniert aber aus naheliegenden Gründen nicht für die Produktion.
Ich habe auch untersucht, wie man ein Byte-Array an die DLL übergibt, aber ich konnte keine Möglichkeit finden, diese in einen anderen Stream zu konvertieren als mit GlobalAlloc, den ich lieber nicht verwenden würde.
Jede Hilfe oder Ideen wäre willkommen.
Danke.
Sie können ein verwaltetes binäres Array an die C ++ / CLI-DLL übergeben. Pin das Array. Dies kann dann in ein STL-String-Objekt konvertiert werden. Sie können dann die STL-Zeichenfolge in ein STL-stringstream-Objekt übergeben, das von iostream erbt. Stellen Sie sich Stringstream als .NET MemoryBuffer-Objekt vor. Übergeben Sie stringstream an Ihr nicht verwaltetes C ++. Das kann wahrscheinlich in & lt; 10 Zeilen Code. Der Nachteil ist, dass die Daten in den Speicher kopiert werden, was ineffizient ist. Für viele Anwendungen bezweifle ich, dass dies ein Problem wäre.
Alternativ könnten Sie Ihre eigene Klasse schreiben, die von stream_buffer erbt, die ein .NET-Stream-Objekt umschließt. (Besser erben statt iostream, wie andere vorschlagen). Das wäre der effizienteste Weg, weil kein Speicher unnötig kopiert werden würde, aber ich würde es nicht tun, wenn die erste Methode schnell genug ist.
Wenn Ihre C ++ - DLL generische Iostream-Objekte akzeptiert (statt nur fstreams), erstellen Sie eine Iostream-Implementierung, die System.IO-Streams umschließt und an die DLL weiterleitet. Dann kann die nicht verwaltete Seite direkt mit dem verwalteten Datenstrom arbeiten.
Ihre C ++ / CLI-Ebene kann eine einfache Schnittstelle für die zu verwendende C # -Seite verfügbar machen, etwa um Byte-Array-Objekte zum Streamen in die Stream-Bibliothek zu übergeben.
Grundsätzlich das Handle / Body-Idiom, bei dem der C ++ / CLI-Layer den Stream umschließt und einen undurchsichtigen Handle an C # zurückgibt, um ihn zu verwenden.
Sie können eine Memorystream
through CLI nicht übergeben. Das Beste, was Sie tun können, ist, einen "Zeiger" (IntPtr) an den Byte-Puffer zu übergeben.
Siehe Wie kann Ich übergebe SpeicherStream-Daten an nicht verwaltetes C ++ - DLL mit P / Invoke? für weitere Details
Ich konnte anhand dieses Posts ein Beispiel erstellen ( PInvoke und IStream ).
Grundsätzlich müssen Sie die IStream-Schnittstelle in C # implementieren. Dann können Sie die benutzerdefinierte MemoryStream
als LPSTREAM
auf der C ++ Seite übergeben. Hier ist ein Codebeispiel, das den Stream nimmt und die Größe erhält (nur ein triviales Beispiel, um zu zeigen, wie es gemacht wird):
C ++ LpWin32Dll.h
%Vor%C ++ LpWin32Dll.cpp
%Vor%C # PInfokusdefinition
%Vor% C # IStream-Implementierung (muss die IStream-Schnittstelle implementieren). Ich habe gerade eine Wrapper-Klasse für die Klasse MemoryStream
erstellt.
C # Verwenden Sie
%Vor% Erstellen Sie eine temporäre Datei. Lassen Sie das Betriebssystem einen temporären Namen für Sie zuweisen, um mehrere Anwendungen zu lösen (Linux kann das tun, ich hoffe, Windows kann).
Temporäre Dateien sind für Multi-Tool-Ketten in Geschäftsanwendungen akzeptabel und werden nur zur Lösung Ihres Problems verwendet. Wenn die Dateien nicht zu groß sind, bleiben sie im Cache und wenn Sie sie schnell genug schließen und löschen, werden sie nicht einmal auf die Festplatte geschrieben.
Tags und Links c# c++ command-line-interface