Jump to content

dev botao

[AcbrLib.NFe] - Problemas no carregamento da Dll


Nelson  A Sousa
Go to solution Solved by Rafael Dias,
  • Este tópico foi criado há 1850 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 to comment
Share on other 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

  • Like 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 to comment
Share on other 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 to comment
Share on other 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 to comment
Share on other 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

Edited by Nelson A Sousa
Link to comment
Share on other 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.

Edited by Nelson A Sousa
Link to comment
Share on other 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.

  • Thanks 1
Link to comment
Share on other 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 to comment
Share on other 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 to comment
Share on other 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

  • Like 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 to comment
Share on other 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.

  • Like 1
Link to comment
Share on other 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.

  • Like 2
  • Thanks 1

 

Link to comment
Share on other sites

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

The popup will be closed in 10 seconds...