Ir para conteúdo
  • Cadastre-se

dev botao

  • Este tópico foi criado há 4842 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Boa noite,

Cá estou eu para pertubar novamente :mrgreen:

Estou usando a ACBR32.dll e ACBR.NET. A DLL foi compilada para STDCALL e

a acbrDll.cs foi modificada de acordo.

Estou com um problema estranho: quando ocorre um erro, a ACBR.NET só consegue

trazer o 1o caracter. Pensei que fosse no lado do Delphi, mas debugando a DLL nada

de errado acontece e a delelê retorna o pchar corretamente (digamos que seja "Modelo não configurado"

o conteúdo do buffer).

No Acbr.net.ECFTest só aparece 'M' . Não sei o que é, pois o DLLImport parece certo e a função

getString também parece correta... Mas deve ter algo que eu não estou fazendo certo aqui.

Ambiente:

Delphi XE

Visual Studio 2010 pro

VSPE (emulador de serial)

Emulador da Bematech

Postado

Respondendo ao meu próprio questionamento: o problema estava no DLLImport.

Em vez de:

[DllImport("ACBr32.dll", CallingConvention= CallingConvention.StdCall)]
Tem que ser:
[DllImport("ACBr32.dll", CallingConvention= CallingConvention.StdCall), Charset=Charset.Unicode]

Reparem o Charset=Charset.Unicode - sem ele não funfa.

Tive de incluir o charset em todas as chamadas DLLImport no ACBrDLL.cs...

Postado

Alo,

Porque você está usando a DLL em STDCALL?

A compilação em STDCALL deixaremos apenas para linguagens que requerem esse tipo de chamada, como VB6 e FoxPro.

Em C# e Java é mais portátil e compatível utilizarmos as dlls em cdecl.

Abs,

Rafael Batiati

ACBrFramework - Automação comercial para todos.

MultiClubes - Soluções para a área de clubes, parques, lazer e entretenimento.

Postado

Alo,

Porque você está usando a DLL em STDCALL?

Simples: "PInvokeStackImbalance was detected". Se compilar em StdCall, esse erro some e dá para começar a trabalhar.

A compilação em STDCALL deixaremos apenas para linguagens que requerem esse tipo de chamada, como VB6 e FoxPro.

Em C# e Java é mais portátil e compatível utilizarmos as dlls em cdecl.

Abs,

Se eu conseguisse funcionar aqui sem StdCall no import. Acabei de recompilar com Cdecl (acertando o ACBRDll.cs de acordo), rebuild na solution do C# e rodar o ECFteste.

Resultado: "PInvokeStackImbalance was detected"

Postado

Resumindo,

Ambiente da DLL: Delphi XE.

Ambiente de ACBr.NET: Visual Studio 2010 Pro.

Dll linkada com StdCall importada com Charset.Unicode: Ok

Dll linkada com StdCall importada sem Charset.Unicode: Stringbuilders preechidos apenas com o 1o char da string.

Dll linkada Cdecl: "PInvokeStackImbalance"

São os resultados que eu consigo aqui.

Agora tem um StackOverflow no ACBr.NET.ECF.VendeItem que parece vir da DLL... Mas isso não é para este post...

Amanhã eu crio o post para esse problema.

Postado

hummmmm....

PInvokeStackImbalance was detected não é uma exception propriamente dita, e sim um "MDA".

A condição de "Imbalance" é detectada por um MDA (Managed Debug Assistants), e jogadas como exception para alertar o desenvolvedor que algo potencialmente errado/perigoso pode estar acontecendo no código.

Faça um teste simples: Compile o .NET em Release e rode, não vai acontecer pois só em Debug há MDAs.

************

Dúvidas e soluções:

Por que isso acontece? Qual parte do código está errada ou perigosa?

Sinceramente não sei. Eu vasculhei todo o código procurando uma declaração incorreta da DLL e não encontrei. Deve ter alguma coisa errada, mas ainda não sei onde.

Por que em STDCALL isso não acontece?

Porque o MDA "PInvokeStackImbalance" só é disparado quando a runtime detecta discordância entre os parâmetros passados para a DLL e o que a DLL espera. Como em STDCALL o mecanismo de passagem de parametros é diferente do CDECL, esse MDA não é acionado.

Por que não usamos STDCALL de uma vez por todas então?

Primeiro para poder suportar o jACBr: para linkar o código C++ do JNI com a DLL é preciso criar uma .lib a partir do código Delphi. A forma que encontrei ficou mais fácil com CDECL.

Segundo para poder compilar no futuro a ACBr32.so e rodar em linux com jACBr e ACBr.NET (projeto Mono).

Como é que eu rodo o ACBr.NET sem esse MDA?

Basta desabilitar esse MDA especificamente para seu projeto: Vá no menu "Debug" > "Exceptions", Localize e expanda "Managed Debug Assistants" e desmarque "PInvokeStackImbalance"

Qual o risco de desabilitar o MDA?

Até agora comigo não aconteceu nada de errado. Mas é possível que essa condição de

"Inbalance" gere falhas de memória em programas que são utilizados por longo tempo ...

Isso será corrigido?

Sendo sincero, eu tinha até me esquecido que isso acontecia. Mas prometo que vou revisar o código e procurar uma solução ou uma explicação racional pra isso!

Como eu contribuo?

Se você conseguir detectar qual(is) método(s) disparam esse MDA, podemos analisar com maior certeza e chegar numa solução definitiva.

**************

Grande abraço!

Rafael Batiati

ACBrFramework - Automação comercial para todos.

MultiClubes - Soluções para a área de clubes, parques, lazer e entretenimento.

  • Este tópico foi criado há 4842 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.