Ir para conteúdo
  • Cadastre-se

dev botao

[AcbrLib.NFe] - Problemas no carregamento da Dll


Nelson  A Sousa
Ver Solução Respondido por Rafael Dias,
  • Este tópico foi criado há 1631 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Olá pessoal,

Usando as Libs no C# com o Visual Studio 17.

Há uns dias atrás tive um problema para carregar as dlls da AcbrLibPosPrinter. Meu erro era que eu as estava empacotando num arquivo de recurso e isso não era mais necessário. O problema foi resolvido.

Fiz o mesmo procedimento com as dlls da ACBrLib.NFe porém voltei a ter problemas ao carregar as dlls. Está retornando o erro de que não foi possível carregar a biblioteca.

A única diferença está nas pastas das dependências, não sei se devo manter os nomes das pastas, ou separar apenas por x32 e x64. 

Ou devo empacotar as dlls da NFe?

Podem me dar uma luz?

AcbrLibNFe.jpg

Link para o comentário
Compartilhar em outros sites

  • Fundadores

As DLLs das pastas de dependências, devem estar no mesmo diretório, da ACBrLib*.dll..

Use a versão de DLL, conforme você compila o seu Binário... Exemplo, se você compila em 32 bits, copie todas as DLLs de "dep" dos subdiretórios "x86", para a mesma pasta da ACBrLibNFe32.dll

  • Curtir 1
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Link para o comentário
Compartilhar em outros sites

23 minutos atrás, Daniel Simoes disse:

As DLLs das pastas de dependências, devem estar no mesmo diretório, da ACBrLib*.dll..

Use a versão de DLL, conforme você compila o seu Binário... Exemplo, se você compila em 32 bits, copie todas as DLLs de "dep" dos subdiretórios "x86", para a mesma pasta da ACBrLibNFe32.dll

Ahh, o erro pode estar aí então.

O  C# no V. Studio tem a opção de x86, x64 e AnyCPU. Como no exemplo está da mesma forma, ou seja AnyCPU, estou deixando  o método construtor decidir qual dll vai ser carregada.

Vou forçar em x86 aqui, copiar as dlls para a raiz do meu EXE e fazer um teste. Volto aqui pra dar o resultado.

Por enquanto muito obrigado @Daniel Simoes!!!

Link para o comentário
Compartilhar em outros sites

  • Fundadores

Mas o tópico nos faz pensar... talvez o @Rafael Dias conheça uma maneira de manter o binário compatível com ambas versões de plataforma...

Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Link para o comentário
Compartilhar em outros sites

9 horas atrás, Daniel Simoes disse:

Mas o tópico nos faz pensar... talvez o @Rafael Dias conheça uma maneira de manter o binário compatível com ambas versões de plataforma...

Sim, um bom exemplo pode ser encontrado no carregamento da SqlServerTypes.

Só que no caso, será necessária uma mudança nas dlls nativas,, elas que vão decidir em qual pasta procurar as dependências. Ou então, uma mudança geral em como arquivar as dlls nativas do Acbr, ou seja, separadamente, cada uma na pasta de sua respectiva plataforma.

Mas essa segunda opção aí talvez seja necessária somente como forma de organizar os arquivos. Não tem tanta necessidade.

Loader.cs

Editado por Nelson A Sousa
Link para o comentário
Compartilhar em outros sites

@Daniel Simoes,

Sim, e que as dlls nativas reconhecessem a mesma estrutura de pastas quando do carregamento das dependências.

A raiz no caso seria a pasta AcbrLib, esta sim, seria colocada na pasta do executável.

Uma vez que a classe de alto nível reconhecesse a plataforma em que está o EXE sendo utilizado. A estrutura de pastas seguiria uma padronização como a sugerida acima.

Dessa forma não importaria a plataforma, se x86 ou x64, e o Acbr rodaria sem problemas.

Editado por Nelson A Sousa
Link para o comentário
Compartilhar em outros sites

4 horas atrás, Daniel Simoes disse:

Isso pode não funcionar muito bem em outras linguagens, como Java, VB... etc...

Bom, sobre o  Java eu não posso falar.

Mas quanto ao  C#, VB e VB.net não tem problema não.

Vou  fazer umas modificações eu mesmo aqui, e, se der certo, eu envio pra averiguação.

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Minha limitação no Delphi não vai permitir que eu faça muita coisa não.

O problema é que as dlls nativas do AcbrLibNFe, não importa a plataforma se x86 ou x64, sempre procuram as dlls dependências na pasta raiz do EXE.

Como as dlls da pasta dep, apesar de terem o mesmo nome, são de plataformas diferentes e não podem ser copiadas para a pasta raiz do EXE.

Para o carregamento das dlls nativas, no caso a ACBrNFFe32.dll e a AcbrNFe64.dll, cada uma em sua respectiva pasta de plataforma, tudo transcorre normalmente. Somente o carregamento das dependências é que não funciona.

Como eu disse, meu conhecimento de Delphi é bem limitado, talvez alguém consiga fazer com que as dlls nativas procurem suas dependências na pasta da própria dll e não na raiz do EXE. Dessa forma poderemos construir um único instalador, já com as versões das duas plataformas x86 e x64.

Para exemplificar coloquei a estrutura de pasta ideal na primeira imagem abaixo. Na segunda imagem coloquei a pequena modificação que precisei fazer no constructor da classe. Apenas acrescentei o path das pastas.

Reparem que as dlls de dependência, apesar de plataformas diferentes, têm o mesmo nome. Isso impede a colocação das mesmas na pasta raiz do EXE, ou se coloca x86 ou se coloca x64. O que torna a verificação de plataforma executada no constructor da segunda foto, de certa forma inútil.

acbrLib.jpg

constructor.jpg

Link para o comentário
Compartilhar em outros sites

para resolver isso é simples.

  1. Você pode distribuir as dll corretas de acordo com o OS do seu cliente, o que é muito simples.
  2. Modificar a classe para carregar das pastas como você fez na mensagem
  3. Copiar as dll corretas nas pasta do windows.

Qualquer uma das opções acima funciona corretamente, não tem necessidade de mexer na lib.

 

Link para o comentário
Compartilhar em outros sites

  • Fundadores
16 horas atrás, Nelson A Sousa disse:

Como eu disse, meu conhecimento de Delphi é bem limitado, talvez alguém consiga fazer com que as dlls nativas procurem suas dependências na pasta da própria dll e não na raiz do EXE. Dessa forma poderemos construir um único instalador, já com as versões das duas plataformas x86 e x64.

Na verdade o Delphi apenas chama a API do Windows, e ela faz a carga da DLL... e o primeiro local (e mais seguro), que o Windows procura, é na mesma pasta do EXE

https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order

  • Curtir 1
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Link para o comentário
Compartilhar em outros sites

13 minutos atrás, Rafael Dias disse:

para resolver isso é simples.

  1. Você pode distribuir as dll corretas de acordo com o OS do seu cliente, o que é muito simples.
  2. Modificar a classe para carregar das pastas como você fez na mensagem
  3. Copiar as dll corretas nas pasta do windows.

Qualquer uma das opções acima funciona corretamente, não tem necessidade de mexer na lib.

Olá @Rafael Dias,

Obrigado pela resposta.

Quanto a sua sugestão 1, eu entendi. Eu só prossegui no post, para o caso de não se saber a OS do cliente, ou no caso de um cliente com várias máquinas com vários OS's. 

Então, para não ter que ter várias versões de distribuição, eu pensei em termos apenas uma distribuição que atendesse qualquer tipo de OS.

 

Quanto à sugestão 2 e 3, eu fiz exatamente isso. Modifiquei a classe e ela carrega as dlls nativas na respectiva pasta da OS.

Nos testes que efetuei aqui, o funcionamento correto só ocorre quando as dlls de dependências estão na raiz do EXE. Note que falei das dependências, neste caso, quando aciono a LibNFe ela não busca na pasta configurada na  classe de alto nível, mas sim na pasta raiz do EXE.

Não sei se estou explicando corretamente...rsrsrs...mas a questão está no carregamento das dlls de dependência.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Solution

Carregamento das dependências de dll nativas seguem o protocolo de procurar nos Paths, isso é o comportamento normal não tem como alterar.

A sequencia é sempre path do exe primeiro, depois paths do windows.

Você pode fazer uma chamada no inicio do seu exe para definir o path para a pasta correta que ela será usada na procura por dll, utilizando o codigo abaixo.

var path = Assembly.GetExecutingAssembly().CodeBase;
path += Environment.Is64BitOperatingSystem ? "ACBrLib\\x64\\" : "ACBrLib\\x86\\";
Environment.SetEnvironmentVariable("PATH", path, EnvironmentVariableTarget.Process);

Com isso nem se faz necessário alteração na classe atual.

Você também pode colocar as libs como resources e extrai-las de acordo com o OS dentro do path do programa, o bom desta opção é que você garante sempre que a lib que esta sendo usada é a versão a qual você testou.

  • Curtir 2
  • Obrigado 1

 

Link para o comentário
Compartilhar em outros sites

  • Este tópico foi criado há 1631 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.

The popup will be closed in 10 segundos...