Domanda

Quando chiamo un codice non gestito C ++ dal mio codice C #, mi sembra di avere un qualche tipo di una perdita di memoria.
Il C ++ legge i dati da un file utilizzando ifstream.read, e lo scrive in un vettore.

Questo accade solo dopo l'aggiornamento a Windows 7, non accade su Vista, ma se uso una versione del dll nativa che è stato compilato su Vista, non cambia nulla!
Se corro direttamente lo stesso codice C ++, senza l'interope gestito, non v'è alcuna perdita di memoria!
Se si esegue il processo gestito, ma all'interno del processo vshost, non c'è perdita di memoria!

Ecco la firma di chiamata:

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

e il nativo uno:

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

Quando chiamo da C ++, io lo chiamo così:

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

Quando guardo i contatori di prestazioni per la memoria gestiti e non gestiti, vedo che tutta la memoria viene dal codice non gestito.
Considerando che il marshalling è piuttosto semplice, non capisco il motivo per cui v'è una differenza tra chiamando il C ++ direttamente o tramite C #.
Anche io non so perché dovrebbe accadere solo su Windows 7 (sia le installazioni di Windows avevano .NET 3.5 SP1).

Qualcuno ha idea di che cosa è la ragione per questo?

Anche se qualcuno sa di uno strumento di profiling di memoria nativa che funziona su Windows 7, sarei felice di sapere (per ora ho appena stampato per consolare tutti allocazione della memoria esplicita e non ci sono differenze).

È stato utile?

Soluzione

Sono sicuro che il problema è legato alla marshalling i tipi di dati C # per le loro parti contatore C ++. Dal momento che si sta effettuando il marshalling il bool valore di ritorno ad un valore di 1 byte con segno, forse si dovrebbe fare lo stesso per gli argomenti della funzione? Il tipo C # bool è di 4 byte, forse si sono perdite lì?

Inoltre, specificando il tipo non gestito per le stringhe possono aiutare.

[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);

Una spiegazione per il commentor:

Per il tipo bool ++ C:

  

In generale, un null puntatore nullo o   valore viene convertito falso, qualsiasi altra   valore viene convertito in true.

...

  

I 1998 definisce libreria standard C ++   una specializzazione del vettore   modello per bool. La descrizione di   la classe indica che la   attuazione dovrebbe imballare la   elementi in modo che ogni BOOL solo usi   un po 'di memoria.

Quindi, praticamente qualsiasi valore si utilizza, si otterrà un ++ booleano c con il valore vero o falso.

Altri suggerimenti

Purtroppo, una volta si coinvolgono le stringhe, non marshalling è semplice.

Avremo bisogno di alcuni ulteriori dati al fine di aiutare a rintracciare questo problema. Potete fornire il seguente

  • metodo natale Firma
  • Come è la memoria per le stringhe gestito in codice nativo?
  • Forse il campione C ++ in cui si utilizza l'API?

Modifica

Provare la seguente firma. Questo dice il CLR di non schierare la memoria in entrambe le direzioni, ma invece passare solo i dati.

    [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);

Ho trovato l'uso del CLR Profiler utile quando trovare la mia perdita di memoria.

Sei sicuro che ci sia una perdita di memoria?

Qual è la vostra base per determinare la perdita di memoria. Tu dici che si può vedere da contatori delle prestazioni, ma che cosa realmente osserva? Vedete una curva coninously in aumento, o uno che si deposita su un alto livello? Un elevato consumo di memoria è spesso confuso per una perdita di memoria.

btw. Puoi pubblicare si C ++ definizione di funzione come bene?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top