Jump to content

dev botao

ECF_GetUltimoErro só retorna o 1o caracter da msg de erro


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

Recommended Posts

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

Link to comment
Share on other sites

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...

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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"

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.