Pergunta

Quando eu chamar um código não gerenciado C ++ a partir de meu código C #, me parece ter algum tipo de perda de memória.
O C ++ lê dados de um arquivo usando ifstream.read, e escreve-o para um Vector.

Isso acontece somente após a atualização para o Windows 7, não acontece no Vista, mas se eu usar uma versão da dll nativa que foi compilado no Vista, isso não muda nada!
Se eu executar o mesmo código C ++ diretamente, sem a interope conseguiu, não há vazamento de memória!
Se eu executar o processo gerenciado, mas dentro do processo vshost, não há vazamento de memória!

Aqui está a assinatura chamada:

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

eo nativa:

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

Quando eu chamá-lo de C ++, eu chamo-lhe assim:

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

Quando eu olhar para os contadores de desempenho para memória gerenciados e não gerenciados, vejo que toda a memória vem do código não gerenciado.
Considerando que o empacotamento é muito simples, eu não entendo porque é que há uma diferença entre chamando o C ++ diretamente ou através de C #.
Eu também não sei por que isso aconteça apenas no Windows 7 (ambos instalações do Windows tinha NET 3.5 SP1).

Alguém tem uma idéia do que é a razão para isso?

Além disso, se alguém souber de uma memória nativa ferramenta que funciona em Windows 7, eu ficaria feliz em saber (por agora eu apenas impresso para consolar todos alocação de memória explícita e não há diferenças) de perfis.

Foi útil?

Solução

Tenho certeza que o problema está relacionado com o empacotamento os tipos de dados C # para os seus C ++ peças contrárias. Desde que você está empacotamento o valor de retorno bool para um valor 1 byte assinado, talvez você deve fazer o mesmo com os argumentos da função? O tipo C # bool é de 4 bytes, talvez você está vazando lá?

Além disso, especificando o tipo não gerenciado para as cordas podem ajudar.

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

Uma explicação para a commentor:

Para o C ++ tipo bool:

Em geral, um nulo-ponteiro zero ou valor é convertido em falso, qualquer outra valor é convertido em realidade.

...

Os 1998 define biblioteca padrão C ++ uma especialização do vector modelo para bool. A descrição da a classe indica que o implementação deve embalar o elementos de modo que cada bool únicos usos um pouco de memória.

Assim, praticamente qualquer valor que você usa, você vai ter um c ++ boolean com o valor verdadeiro ou falso.

Outras dicas

Infelizmente, uma vez que envolvem cordas, sem triagem é simples.

Nós vamos precisar de mais alguns dados, a fim de ajudá-lo a rastrear o problema. Você pode fornecer o seguinte

  • Método Native Assinatura
  • Como é a memória para as cordas gerenciados em código nativo?
  • Talvez a amostra C ++, onde você usa a API?

Editar

Tente o seguinte assinatura. Isso informa o CLR não para a memória marechal em ambas as direções, mas em vez disso só passar os dados.

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

Eu encontrei o uso do CLR Profiler útil quando encontrar o meu vazamento de memória.

Você tem certeza de que há um vazamento de memória?

Qual é a sua base para determinar o vazamento de memória. Você diz que você pode vê-lo a partir de contadores de desempenho, mas o que você realmente observar? Você vê uma curva coninously subindo, ou uma que se instala em um nível elevado? Um alto consumo de memória é muitas vezes confundida por um vazamento de memória.

btw. você pode enviar-lhe C ++ definição de função, bem como?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top