Frage

Wenn ich einen nicht verwaltete C ++ Code aus meinem C # -Code nenne, scheine ich eine Art von Speicherverlust zu haben.
Die C ++ liest Daten aus einer Datei ifstream.read verwendet wird, und schreibt sie in einem Vektor.

Dies geschieht erst nach Upgrade auf Windows 7, geschieht nicht auf Vista, aber wenn ich eine Version der nativen DLL verwenden, die auf Vista kompiliert wurde, es ändert nichts!
Wenn ich den gleichen C ++ Code direkt ausführen, ohne das verwaltete interope, gibt es keinen Speicherverlust!
Wenn ich den verwalteten Prozess laufen, aber innerhalb des vshost Prozesses gibt es kein Speicherleck!

Hier ist der Aufruf Signatur:

        [DllImport(DllPath, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.I1)]
    public static extern bool MyMethod(
        int x, 
        string  y, 
        string  z, 
        bool    v, 
        bool    w);

und die native ein:

MyDll_Export bool APIENTRY MyMethod(
int x,
const wchar_t*  y, 
const wchar_t*  z,
bool v,
bool w)

Wenn ich es von C ++ nennen, ich nenne es wie folgt aus:

MyMethod(1, L"My String 1", L"My String 2", true, true)

Wenn ich die Leistungsindikatoren sucht verwalteten und nicht verwalteten Speicher, sehe ich, dass der gesamte Speicher aus dem nicht verwalteten Code kommt.
Bedenkt man, dass das Marshalling ziemlich einfach ist, verstehe ich nicht, warum ein Unterschied ist die C zwischen die Telefonnummer ++ C # direkt oder über.
Ich weiß auch nicht, warum dies nur auf Windows 7 (sowohl Windows-Installationen hatten .net 3.5 SP1) passieren würde.

Hat jemand eine Idee, was ist der Grund dafür?

Auch wenn jemand eines nativen Speicherprofilierungswerkzeuges weiß, dass 7 auf Fenster arbeitet, würde ich gerne wissen (für jetzt habe ich gerade gedruckt alle explizite Speicherzuweisung zu trösten und es gibt keine Unterschiede).

War es hilfreich?

Lösung

Ich bin sicher, dass das Problem auf die Marshalling C # Datentypen zu ihren C ++ Gegenteilen verwendet ist. Da Sie den Rückgabewert bool zu einem signierten 1-Byte-Wert marshallen, vielleicht sollten Sie das gleiche auf die Funktionsargumente tun? Der C # Bool Typ ist 4 Bytes, vielleicht geben Sie sind undicht?

Auch die nicht verwaltete Typ für die Saiten spezifizieren kann helfen.

[DllImport(DllPath, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool MyMethod(
        int x,
        [MarshalAs(UnmanagedType.LPWStr)]
        [In] string y,
        [MarshalAs(UnmanagedType.LPWStr)]
        [In] string z,
        [MarshalAs(UnmanagedType.I1)]
        bool v,
        [MarshalAs(UnmanagedType.I1)]
        bool w);

Eine Erklärung für den commentor:

Für die C ++ Bool Typ:

  

Im Allgemeinen ist eine Null oder Null-Pointer   Wert wird auf false umgewandelt, jede andere   Wert auf true umgewandelt werden.

...

  

Die 1998 C ++ Standard Library definiert   eine Spezialisierung des Vektors   Vorlage für Bool. Die Beschreibung   die Klasse zeigt an, dass die   Umsetzung sollte die Packung   Elemente, so dass jeder Bool nur Anwendungen   ein Bit Speicher.

So, so ziemlich, was Wert, den Sie verwenden, erhalten Sie einen c ++ boolean mit dem Wert wahr oder falsch erhalten.

Andere Tipps

Leider, wenn Sie Strings beinhalten, ist kein Rangieren einfach.

Wir werden einige weitere Daten, um benötigen Sie dieses Problem aufzuspüren zu helfen. Können Sie das folgende

liefern
  • Native Methode Signatur
  • Wie wird der Speicher für die Saiten in nativen Code verwaltet?
  • Vielleicht ist die C ++ Beispiel, wo Sie die API verwenden?

Bearbeiten

Versuchen Sie, die folgende Signatur. Dies teilt den CLR nicht Speicher in beiden Richtungen Marschall, sondern passieren nur die Daten in.

    [DllImport(DllPath, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.I1)]
    public static extern bool MyMethod(
            int x, 
            [In] string  y, 
            [In] string  z, 
            bool    v, 
            bool    w);

fand ich die Verwendung der CLR Profiler hilfreich, wenn mein Speicherleck zu finden.

Sind Sie sicher, dass es ein Speicherleck?

Was ist Ihre Basis des Speicherverlust zu bestimmen. Sie sagen, dass Sie es von Leistungsindikatoren sehen, aber was beobachten Sie eigentlich? Sehen Sie eine coninously ansteigende Kurve, oder eine, die auf hohem Niveau absetzt? Ein hoher Speicherverbrauch wird oft verwechselt für ein Speicherleck.

btw. Können Sie nach Ihnen C als auch Funktionsdefinition ++?

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