pérdida de memoria cuando se llama a código no administrado desde código administrado en Windows 7

StackOverflow https://stackoverflow.com/questions/1505489

Pregunta

Cuando llamo a un código C ++ no administrado de mi código C #, me parece que tienen algún tipo de pérdida de memoria.
El C ++ lee datos de un archivo usando ifstream.read, y lo escribe en un Vector.

Esto ocurre sólo después de actualizar a Windows 7, no sucede en Vista, pero si uso una versión de la DLL nativa que fue compilado en Vista, no cambia nada!
Si funciono el mismo código C ++ directamente, sin la interope administrado, no hay pérdida de memoria!
Si corro el proceso gestionado, pero dentro del proceso de vshost, no hay pérdida de memoria!

Aquí está la firma de llamada:

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

y el nativo de uno:

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

Cuando la llamo desde C ++, lo llamo así:

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

Cuando miro a los contadores de rendimiento de la memoria administrado y no administrado, veo que toda la memoria proviene del código no administrado.
Teniendo en cuenta que el cálculo de referencias es bastante simple, que no entiendo por qué hay una diferencia entre llamar al C ++ directamente oa través de C #.
Asimismo, no sé por qué esto sucede sólo en Windows 7 (ambos tenían instalaciones de Windows .NET 3.5 SP1).

¿Alguien tiene una idea de lo que es la razón de esto?

Además, si alguien sabe de una herramienta de perfiles de memoria nativa que funciona en Windows 7, estaría contento de saber (por ahora he acaba de imprimir a la consola toda asignación de memoria explícita y no hay diferencias).

¿Fue útil?

Solución

Estoy seguro de que el problema está relacionado con el cálculo de referencias a los tipos de datos de C # a sus homólogos de C ++. Puesto que usted está calculando el valor bool retorno a un valor de 1 byte con signo, tal vez debería hacer lo mismo con los argumentos de la función? El tipo C # bool es de 4 bytes, tal vez se filtra la hay?

Además, especificando el tipo no administrado para las cadenas pueden ayudar.

[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 explicación para la commentor:

Para el C ++ tipo bool:

  

En general, un null-puntero cero o   valor se convierte a falso, cualquier otra   valor se convierte en verdadera.

...

  

Los 1998 define biblioteca de C ++ estándar   una especialización del vector   plantilla para bool. La descripción de   la clase indica que la   implementación debe empacar el   elementos para que cada bool únicos usos   un poco de memoria.

Por lo tanto, casi todo lo de valor que utilice, obtendrá un booleano ++ c con el valor verdadero o falso.

Otros consejos

Lamentablemente, una vez se involucran cuerdas, sin cálculo de referencias es simple.

Vamos a necesitar algunos datos más con el fin de ayudar a rastrear este problema. ¿Puede proporcionar la siguiente

  • Método Nativo Firma
  • ¿Cómo es la memoria para las cadenas logró en código nativo?
  • Tal vez el C ++ muestra en la que se utiliza la API?

Editar

Trate la siguiente firma. Esto le dice al CLR no reunir la memoria en ambas direcciones y por tanto solo pasar los datos en.

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

Me pareció que el uso de la CLR Profiler útil cuando la búsqueda de mi pérdida de memoria.

¿Está seguro de que hay una pérdida de memoria?

¿Cuál es su base para determinar la pérdida de memoria. Usted dice que se puede ver desde los contadores de rendimiento, pero ¿qué es lo que realmente observado? ¿Usted ve una curva ascendente coninously, o uno que se asienta en un alto nivel? Un alto consumo de memoria se confunde a menudo por una pérdida de memoria.

por cierto. Se puede publicar que C ++ definición de función así?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top