SOLVED - DLL steigt in VS2015 aus
-
Hallo.
Mit folgender Funktion konnte ich bisher in VS2013 alle printf Ausgabe in eine Console úmleiten, da der Code teil einer DLL ist, welche ich in C# nutze.
Gleich vorweg, ich kann leider diese DLL nicht mit dem C# Projekt debuggen, weil die DLL eine statische Bibliothek ausführt, welche ohne Basic Runtime Checks kompiliert wurde, so dass ich das für meine DLL auch so einstellen musste.#define COMMANDLINEOUTPUT_H int AllocConsoleOutputFkt(){ int hConHandle; long lStdHandle; FILE *fp; AllocConsole(); lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE); hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); fp = _fdopen(hConHandle, "w"); *stdout = *fp; setvbuf(stdout, NULL, _IONBF, 0); return 0; } extern "C" __declspec(dllexport) int AllocConsoleOutputParalution(){ return AllocConsoleOutputFkt(); }Jetzt arbeite ich mit VS2015 und sobald ich die DLL ausführe, steigt das C# Programm ohne Fehlermeldung aus. Ich konnte durch auskommentieren herausbekommen, dass das Programm in Zeile 14, also fp = _fopen... aussteigt.
Hat jemand eine Idee, woran das liegen kann? Ich kann leider keinen Haltepunkt setzen und checken, welchen Wert hConHandle hat.
-
http://stackoverflow.com/questions/9020790/using-stdin-with-an-allocconsole
Was macht
AllocConsole(); freopen("CONIN$", "r", stdin); freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr);?
-
Funktioniert super.
Anbei der Code, wie man von C# aus den stdout einer dll, die man über System.Runtime.Interopt Service aufruft, auf eine console bekommt. Ist wunderbar zum debuggen.
CommandLineOutput.h
#define COMMANDLINEOUTPUT_H int AllocConsoleOutputFkt(){ int hConHandle; long lStdHandle; FILE *fpIn; FILE *fpOut; FILE *fpErr; AllocConsole(); //fpIn = freopen("CONIN$", "r", stdin); fpOut = freopen("CONOUT$", "w", stdout); //fpErr = freopen("CONOUT$", "w", stderr); *stdout = *fpOut; setvbuf(stdout, NULL, _IONBF, 0); return 0; } extern "C" __declspec(dllexport) int AllocConsoleOutputParalution(){ return AllocConsoleOutputFkt(); }In C# dann einfach die Funktion zum Aufrufen einmal ausführen:
[DllImport(<Filename of the dll library *.dll>, EntryPoint = "AllocConsoleOutputParalution", CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void AllocConsoleOutput();Und schon ploppt ein Commandwindow auf und man sieht die Konsolenanwendung durchlaufen.
Danke!
-
Die Zeile
*stdout = *fpOut;ist nicht nötig.Der Returnwert von
freopenist NULL (im Fehlerfall) oder sonst genau das was man übergeben hat.
Wennfreopenfehlschlägt crasht dein Programm also.
Ansonsten macht es sinngemäss*stdout = *stdout- also nix sinnvolles.Und da man FILE structs als "opaque" behandeln sollte (=nur mit dem FILE* Zeiger und den stdio Funktionen arbeiten, niemals den Zeiger dereferenzieren), würde ich die Zeile lieber wegmachen.
Was das
setvbufangeht bin ich mir nicht sicher ob das nötig ist. Kann aber vermutlich auch nicht schaden. Bzw. wenn "line buffered" für dich schon zu viel ist, dann ist es natürlich nötig.Ich würde also eher das vorschlagen
int AllocConsoleOutputFkt() { AllocConsole(); if (freopen("CONOUT$", "w", stdout)) return setvbuf(stdout, NULL, _IONBF, 0); else return errno; }