pinvokestackimbalance – como posso corrigir isso ou desativá-lo?

Eu apenas mudei para o vs2010 do vs2008. Exatamente a mesma solução, exceto que agora todas as chamadas para um C ++ dll geram uma exceção ‘pinvokestackimbalance’.

Essa exceção não é acionada em 2008. Tenho access completo à DLL do C ++ e ao aplicativo de chamada. Não parece haver nenhum problema com o pinvoke, mas esse problema está tornando impossível a debugging de outros problemas; o IDE está parando constantemente para me contar sobre essas coisas.

Por exemplo, aqui está a assinatura do C #:

[DllImport("ImageOperations.dll")] static extern void FasterFunction( [MarshalAs(UnmanagedType.LPArray)]ushort[] inImage, //IntPtr inImage, [MarshalAs(UnmanagedType.LPArray)]byte[] outImage, //IntPtr outImage, int inTotalSize, int inWindow, int inLevel); 

Aqui está o que parece no lado do C ++:

 #ifdef OPERATIONS_EXPORTS #define OPERATIONS_API __declspec(dllexport) #else #define OPERATIONS_API __declspec(dllimport) #endif extern "C" { OPERATIONS_API void __cdecl FasterFunction(unsigned short* inArray, unsigned char* outRemappedImage, int inTotalSize, int inWindow, int inLevel); } 

O que há de diferente entre o vs2010 e o vs2008 que poderia causar essas exceções? Devo adicionar um conjunto diferente de parâmetros à diretiva DllImport?

Primeiro, entenda que o código está errado (e sempre foi). O “pInvokeStackImbalance” não é uma exceção em si, mas um assistente de debugging gerenciado. Ele estava desativado por padrão no VS2008, mas muitas pessoas não o ativaram, portanto, ele está ativado por padrão no VS2010. O MDA não é executado no modo Liberação, por isso não será acionado se você criar para lançamento.

No seu caso, a convenção de chamada está incorreta. DllImport padronizado como CallingConvention.WinApi , que é idêntico ao CallingConvention.StdCall para o código da área de trabalho x86. Deve ser CallingConvention.Cdecl .

Isso pode ser feito editando a linha [DllImport("ImageOperations.dll")] como:

 [DllImport("ImageOperations.dll", CallingConvention = CallingConvention.Cdecl)] 

Para mais informações, consulte esta referência do MSDN.

Para desligá-lo:

  1. CTRL + ALT + E
  2. Em “Assistentes de Depuração Gerenciados”, desmarque PInvokeStackImbalance.

Melhor resolver esta questão não é muito difícil aqui eu estou mencionando alguns dos methods, pode mesmo que alguns dos meus amigos mencionados acima. Eu estou trabalhando com PCSC um aplicativo de cartão inteligente que eu gasto cerca de uma semana, ficar chateado fez muitas mudanças finalmente tenho as soluções.

Para mim, o seu trabalho com o PInvoke Extension que instalei para o VS2010 pode ser baixado aqui http://www.red-gate.com/products/dotnet-development/pinvoke/

Faça o download e instale-o, Feche o visual studio e abra novamente você pode encontrar a extensão na Barra de Menus. insira a descrição da imagem aqui

Se o erro é por causa da assinatura não coincidindo basta clicar em PInvoke.net> Inserir Assinaturas PInvoke

A nova janela aparecerá como abaixo insira a descrição da imagem aqui

Digite o nome da dll e clique em busca você pode ver todas as funções dessa dll na janela de resultados de pesquisa, clique na function que você irá obter uma assinatura para essa function particular.

Use essa assinatura e você precisa modificar seus programas de acordo com essa assinatura, principalmente o tipo de dados.

Isso resolve o meu problema, você pode ter um problema diferente como callingConvention ou atributos adicionais precisam especificar ao importar dll.

Codificação Feliz Seja bem!

Eu tenho esse problema também ao usar o VS2010. O que é: o Visual Studio usa como padrão o código de 64 bits para ‘qualquer CPU’. Os pointers para variables ​​(por exemplo, seqüências de caracteres) agora se tornam 64 bits ao chamar suas DLLs externas, onde todos os seus Dlls confiáveis ​​e confiáveis ​​usam pointers de 32 bits.

Não assuma que há algo errado com suas Dlls, não há.

Altere suas configurações do VS para gerar o código X86 como este (Express versions of C #)

  1. vá para Ferramentas -> Opções.
  2. No canto inferior esquerdo da checkbox de diálogo Opções, marque a checkbox que diz “Mostrar todas as configurações”.
  3. Na exibição em tree à esquerda, selecione “Projetos e soluções”.
  4. Nas opções à direita, marque a checkbox que diz “Mostrar configurações avançadas de compilation”.
  5. Clique OK.
  6. Vá para Build -> Configuration Manager …
  7. Na coluna Plataforma, ao lado do seu projeto, clique na checkbox de combinação e selecione “”.
  8. Na configuração “Nova plataforma”, escolha “x86”.
  9. Clique OK.
  10. Clique em Fechar.

Percebo também que, embora os computadores tenham dobrado de energia a cada 12 meses, meu computador atual com 1gig de RAM não parece ser mais rápido do que o meu primeiro 486 com 4 Meg. Não se preocupe em usar o código de 64 bits, ele não será mais rápido ou melhor, porque ele é construído sobre uma enorme torre de inchaço orientada a objects.

Eu tentei chamar dll com o CallingConvention é ThisCall e funcionou para mim. Aqui está o meu código trabalhando com o BLOB MS Sql Server.

 [DllImport("sqlncli11.dll", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.ThisCall)] private static extern SafeFileHandle OpenSqlFilestream( string FilestreamPath, UInt32 DesiredAccess, UInt32 OpenOptions, byte[] FilestreamTransactionContext, UInt32 FilestreamTransactionContextLength, Int64 AllocationSize); 

Mais em: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention(v=vs.110).aspx