2010-03-21 14 views

Antwort

7

Ich bin ziemlich sicher, dass es einen Weg gibt, aber es ist wahrscheinlich eine schlechte Idee. Wie würden Sie garantieren, dass die Laufzeit während der internen Verarbeitung, die die errno beeinflusst hat, einige CRT-Funktionen nicht aufgerufen hat?

Aus dem gleichen Grund sollten Sie auch nicht direkt GetLastError anrufen. DllImportAttribute bietet eine SetLastError-Eigenschaft, sodass die Laufzeitumgebung den letzten Fehler sofort erfassen und an einem Speicherort speichern kann, den der verwaltete Code unter Verwendung von Marshal.GetLastWin32Error lesen kann.

Ich denke, die robusteste, was Sie in diesem Fall tun konnten, ist ein C-DLL machen, die sowohl die tatsächliche C Arbeit und die Erfassung der errno führt. (Beachten Sie, dass nur ein Wrapper rund um die errno Erfassung hätte die oben genannten Bedenken noch.)

+0

Ja, ich würde dem zustimmen. Es wäre wahrscheinlich besser, einen C-Wrapper als Zielfunktion zu definieren, der wiederum den Wert von errno zurückgibt. – supercheetah

2

Ja, es ist möglich - GetLastError tut genau das. Wie der binarycoder jedoch darauf hingewiesen hat, sollten Sie dies nicht direkt tun, sondern SetLastError auf DllImport setzen, damit dies automatisch ausgeführt und zwischengespeichert wird (und um Multithreading-Probleme oder durch Laufzeit aufgerufene Funktionen zu vermeiden, die den Wert errno modifizieren) P/Aufgerufene Funktion, überprüfen Sie ihren Rückgabe-Status, und wenn es eine Fehlerbedingung zeigt - werfen Sie Win32Exception, die den Wert des letzten Fehlers automatisch liest. Ja, sogar auf Mono unter Linux.

2

Die Lösung ist SetLastError auf DllImport zu verwenden. Dadurch speichert die Runtime den letzten Fehler, sodass auf sie von Marshal.GetLastWin32Error zugegriffen werden kann.

Es gibt zwei Probleme mit Aufruf GetLastError direkt:

  • Die Laufzeit könnte irgendwann nach der PInvoke zurückkehrt, bevor Sie in der Lage sind, um die letzten Fehler
  • Mehrere .NET Threads auf dem gleichen nativen wohnen kann bekommen Faden. Dies kann dazu führen, dass 2 .NET-Threads PInvokes ausführen, die nativen Bibliotheken nicht besser kennen, dann würde der letzte Fehler überschrieben. Also thread A in .NET Thread Thread B den letzten Fehler (möglicherweise).
+0

Können Sie ein Beispiel für die Syntax für 'SetLastError' auf' DllImport' zeigen? –

Verwandte Themen