2016-06-30 3 views
0

Ich habe folgende C++ Funktion:PInvoking Funktion mit Ausgangsparameter

int my_func(char* error) { 
    // Have access here to an Exception object called `ex` 
    strcpy(error, ex.what()); 
    return 0; 
} 

ich es so in C# bin PInvoking:

[DllImport("pHash.dll", CallingConvention = CallingConvention.Cdecl)] 
private static extern int my_func(
    [MarshalAs(UnmanagedType.LPStr)] 
    StringBuilder error); 

Und mit wie dies im Code (immer C# natürlich .):

StringBuilder error = new StringBuilder(); 
int returnValue = my_func(error); 

Wenn ich das laufen, schrecklich das Programm abstürzt (was bedeutet, dass Abstürze ohne Ausnahme ist gerade schließt, ist das i t). Was mache ich falsch?

+1

[Matthew] (http://stackoverflow.com/a/38117156/5528593) scheint die Antwort richtig zu sein. Aber für Ihre nächste Frage: Bitte teilen Sie uns zumindest die Fehlermeldung mit. "Crashes terribly" ist kein so guter Hinweis wie eine Ausnahmebotschaft. –

+0

Es gibt keine Ausnahme, das ist das Problem. Das Programm wird beendet und das ist es ... – Andry

+0

Die Schnittstelle dieser Funktion ist irreparabel defekt. Sie können nicht vor Pufferüberläufen schützen. Sie müssen den Anrufer die Länge des Puffers übergeben lassen und dann sicherstellen, dass Sie nicht über das Ende des Puffers hinaus kopieren. –

Antwort

2

Die Frage hier ist: Wie weiß Ihr Code, wie groß der String-Puffer sein sollte?

Normalerweise hätten Sie eine Möglichkeit, es herauszufinden. In Ermangelung dieser Information ist das einzige, was Sie tun können, die StringBuilder zu initialisieren, um so groß wie die größte Zeichenfolge zu sein, die Sie erwarten, bevor Sie die Funktion aufrufen.

Zum Beispiel:

 StringBuilder error = new StringBuilder(1024); // Assumes 1024 chars max. 

Ihr Code ein StringBuilder mit einer Standardkapazität ist vorbei, das ist (glaube ich) 16, so dass jede Zeichenfolge größer als das wird zu einem Absturz führen.