Ir para conteúdo
  • Cadastre-se

dev botao

Sintaxe para iniciar LIB e receber retorno...


Ver Solução Respondido por Delfos Sistemas,

Recommended Posts

  • Membros Pro

Olá,

Não sei se vocês vão poder me ajudar, pois uso uma linguagem pouco conhecida (Visual Object) e estou tendo dificuldades em usar LIBs que retornam valores, por exemplo ACBrLibCEP e ACBrLibConsultaCNPJ.

Eu declaro cada função da LIB desta forma:

_DLL FUNCTION CNPJ_Inicializar(eArqConfig AS STRING, eChaveCrypt AS STRING ) AS INT PASCAL:ACBrConsultaCNPJ32.CNPJ_Inicializar

e nas funções que retornam valores eu declaro assim:

_DLL FUNCTION CNPJ_Consultar(eCNPJ AS STRING, eProvedor AS INT, sResposta REF STRING, esTamanho REF INT ) AS INT PASCAL:ACBrConsultaCNPJ32.CNPJ_Consultar

No programa eu uso desta forma:

    LOCAL V_Retorno
    LOCAL V_Dados AS STRING
    LOCAL V_Tamanho AS INT    
    
    V_Tamanho := 500
    V_Dados := Space(V_Tamanho)    
    
    V_Retorno := CNPJ_Inicializar('ACBrLib.ini','')   

Obs: Conteúdo da variavel V_Retorno = 0

    V_Retorno := CNPJ_Consultar('13397985000182',2,@V_Dados,@V_Tamanho)

Obs: Conteudo das variaveis V_Retorno, V_Dados e V_Tamanho = ''

    V_Retorno := CNPJ_Finalizar()

Obs: Conteúdo da variavel V_Retorno = ''

 

Eu uso a LIB ACBrLibMail , enviando emails sem problemas, porém nela não uso nenhuma função que retorna valores, apenas envio informações:

    V_Retorno := MAIL_Inicializar('ACBrLib.ini','')
    V_Retorno := MAIL_Clear()    

    V_Retorno := MAIL_ConfigLer('ACBrLib.ini')
    V_Retorno := MAIL_ConfigGravarValor("Email","Senha","123456")
    V_Retorno := MAIL_ConfigGravar("ACBrLib.ini")

    V_Retorno := MAIL_AddAddress("[email protected]","")
    V_Retorno := MAIL_SetSubject("Teste de envio de email...")
    V_Retorno := MAIL_AddBody('teste de envio de email automaticamente')
    V_Retorno := MAIL_Send(0)
    V_Retorno := MAIL_Finalizar()
 

Vocês teriam alguma dica de onde estou errando?

Obrigado,

Sergio

Link para o comentário
Compartilhar em outros sites

  • Consultores

Bom dia!

Por favor, se você configurar o log da Lib, na seção [Principal] no seu arquivo ACBrLib.ini

image.png

Ele trás as informações?

12 horas atrás, Delfos Sistemas disse:

V_Retorno := CNPJ_Consultar('13397985000182',2,@V_Dados,@V_Tamanho)

Não conheço sua linguagem, mas chuto que aqui você esteja passando um ponteiro para o valor de V_Dados e V_Tamanho.

Não é possível passar o valor direto?

V_Retorno := CNPJ_Consultar('13397985000182',2,V_Dados,V_Tamanho)

 

  • Curtir 1
Consultor SAC ACBr

Diego Folieni
Ajude o Projeto ACBr crescer - Assine o SAC

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

Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil


Participe de nosso canal no Discord e fique ainda mais próximo da Comunidade !!

Link para o comentário
Compartilhar em outros sites

  • Membros Pro

Oi Diego,

Obrigado pelas dicas, principalmente a questão do log. Assim vou conseguir entender o que pode estar acontecendo.

Vou testar também a sua outra dica sobre passar o valor direto.

Assim que testar eu coloco o resultado aqui.

obrigado!

Sergio

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

  • Membros Pro

Oi Diego,

Estou enviando abaixo o resultado do log:

16/01/24 13:10:33:804 - TLibConsultaCNPJConfig.AplicarConfiguracoes: c:\sistemas\CoPg_Soares\ACBrLib.ini
16/01/24 13:10:33:804 - TLibConsultaCNPJConfig.Gravar: c:\sistemas\CoPg_Soares\ACBrLib.ini
16/01/24 13:10:33:805 - TLibConsultaCNPJConfig.Gravar - Feito
16/01/24 13:10:33:805 - TLibConsultaCNPJConfig.AplicarConfiguracoes - Feito
16/01/24 13:10:33:805 - TLibConsultaCNPJConfig.Ler - Feito
16/01/24 13:10:33:805 - LIB_Inicializar( ACBrLib.ini,  )
16/01/24 13:10:33:806 -    ACBrLibConsultaCNPJ - 0.0.0.38
16/01/24 13:10:34:514 - CNPJ_Consultar ( 13397985000182,2 )
16/01/24 13:10:34:514 - Travar
16/01/24 13:10:34:878 - Destravar
16/01/24 13:10:34:878 -    MoverStringParaPChar. StrLen:607, BufLen:607
16/01/24 13:10:34:880 -    SetRetorno(0, [Consulta]
Abertura=18/03/2011
Bairro=DISTRITO E AREA INDUSTRIAL
CEP=18120000
CNAE1=25.39-0-01 Serviços de usinagem, torneiria e solda
CNAE2=25.42-0-00 Fabricação de artigos de serralheria, exceto esquadrias46.63-0-00 Comércio atacadista de máquinas e equipamentos para uso industrial; partes e peças46.87-7-03 Comércio atacadista de resíduos e sucatas metálicos
Cidade=MAIRINQUE
Complemento=LOTE AREA B
EmpresaTipo=MATRIZ
Endereco=RUA AMF DO BRASIL
Fantasia=
NaturezaJuridica=213-5 - Empresário (Individual)
Numero=253
RazaoSocial=EDSON LUIZ SOARES SAO ROQUE
Situacao=ATIVA
UF=SP
)
16/01/24 13:10:52:585 - LIB_Finalizar
16/01/24 13:10:52:585 - Finalizar

Sobre passar o valor direto (sem o @), não fez diferença no retorno das variáveis e nem no resultado do log...

Pelo log, a função parece estar funcionando corretamente... Se nao conseguir fazer a função receber o retorno, vou acabar pegando o resultado do log e extraindo as informações...

Seria uma gambiarra mas funcionaria....

Você tem alguma outro "chute" do que poderia ser?

Obrigado,

Sergio

 

Link para o comentário
Compartilhar em outros sites

  • Consultores

Boa tarde @Delfos Sistemas

Também não conheço sua linguagem, mas seguem sugestões.

1. Talvez não tenha que alocar os espaços na V_Dados (aparentemente está correto como fez, mas pode ser uma peculiaridade da linguagem). Tente sem este passo 

V_Dados := Space(V_Tamanho)    

2. Talvez, você tenha que informar, na declaração da função, que a variável é de retorno, conforme exemplos hipotéticos a seguir

_DLL FUNCTION CNPJ_Consultar(eCNPJ AS STRING, eProvedor AS INT, VAR sResposta REF STRING, VAR esTamanho REF INT ) AS INT PASCAL:ACBrConsultaCNPJ32.CNPJ_Consultar

_DLL FUNCTION CNPJ_Consultar(eCNPJ AS STRING, eProvedor AS INT, RET sResposta REF STRING, RET esTamanho REF INT ) AS INT PASCAL:ACBrConsultaCNPJ32.CNPJ_Consultar

 

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

  • Membros Pro

Oi Renato,

Obrigado pelas dicas, mas já tentei não alocar os espaços na variável V_Dados e não houve mudança no resultado.

Tentei também alocar um valor nulo (V_Dados := '') e também não funcionou.

Também tentei não declarar o tipo (string) e ai já deu erro na compilação.

Sobre a declaração da função, fui reler e pesquisar para ver se tem como informar como você sugeriu, porém a forma é esta que estou fazendo.

Quando eu coloco "REF" é justamente para informar que é uma variável de retorno.

Eu faço desta forma quando utilizo outra LIB, de outra empresa, porém na outra LIB eu não declaro desta forma (_DLL FUNCTION) eu apenas instancio uma variável citando o nome da DLL:

local oDLL as OLEAutoObject

 oDLL := OLEAutoObject{ 'DLLTeste.DLL' }

oDLL:Funcao(var1, var2, @var3, @var4)

Até tentei instanciar a LIB ACBr desta forma mas não funcionou....

Pessoal, eu agradeço muito a colaboração, mas se ninguém tiver mais sugestões, vou fazer mesmo a gambiarra, pois pelo menos eu consigo obter as informações.

Obrigado,

Sergio

Link para o comentário
Compartilhar em outros sites

  • Consultores

Realmente a ajuda foi no chutometro.

Em uma pesquisa rápida vi que sua linguagem nasceu da ideia de trazer o Clipper para o Windows, mas não encontrei exemplos de consumo de dlls.

Não temos nenhum exemplo para basearmos os testes e, caso você consiga resolver o problema do retorno, ficaremos gratos se puder compartilhar um para disponibilizarmos para a comunidade.

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

  • Consultores

Em um último palpite, apelei ao "Novo Stack OverFlow"(?) e questionei se existe alguma outra maneira de consumir uma Dll além da que está utilizando:

Esta resposta faz algum sentido para você? (novamente, não tenho conhecimento na sua linguagem, então é muito no "achometro")

Voce:
Existe alguma maneira diferente desta para fazer o bind do método da dll? _DLL FUNCTION CNPJ_Consultar FROM "ACBrConsultaCNPJ32.dll" ; PARAMETER eCNPJ AS STRING, eProvedor AS INT, ; sResposta REF STRING, esTamanho REF INT ; RETURNS INT PASCAL

Novo StackOverFlow(?)GPT:
A forma que você está utilizando, com _DLL FUNCTION, é a maneira padrão de declarar funções externas em Visual Objects. No entanto, se estiver enfrentando problemas, ou se deseja explorar alternativas, pode considerar utilizar a função LoadLibrary() para carregar a DLL dinamicamente e, em seguida, usar GetProcAddress() para obter um ponteiro para a função desejada. Aqui está um exemplo simplificado:

// Carregando a DLL dinamicamente
hDll := LoadLibrary("ACBrConsultaCNPJ32.dll")

// Verificando se a DLL foi carregada corretamente
IF hDll <> 0
   // Obtendo um ponteiro para a função CNPJ_Consultar
   @CNPJ_Consultar := GetProcAddress(hDll, "CNPJ_Consultar")

   // Chamando a função como de costume
   LOCAL resultado, resposta, tamanhoResposta
   tamanhoResposta := 256
   resposta := Space(tamanhoResposta)

   resultado := CNPJ_Consultar("12345678901234", 1, @resposta, @tamanhoResposta)

   // Trabalhando com a resposta
   ? "Resultado da consulta:", resultado
   ? "Resposta da consulta:", resposta

   // Fechando a DLL
   FreeLibrary(hDll)
ELSE
   ? "Erro ao carregar a DLL"
ENDIF

Neste exemplo, LoadLibrary é usado para carregar a DLL dinamicamente, e GetProcAddress é usado para obter um ponteiro para a função desejada. É importante verificar se a DLL foi carregada corretamente (hDll <> 0) antes de prosseguir.

Embora esta abordagem seja mais flexível, ela também requer um pouco mais de código e cuidado, pois você precisa gerenciar a carga e descarga da DLL manualmente. Além disso, é fundamental que o nome da função passado para GetProcAddress corresponda exatamente ao nome exportado pela DLL.

Certifique-se de compreender as implicações desta abordagem e avaliar se é apropriada para a sua situação específica.

  • Curtir 1
Consultor SAC ACBr

Diego Folieni
Ajude o Projeto ACBr crescer - Assine o SAC

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

Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil


Participe de nosso canal no Discord e fique ainda mais próximo da Comunidade !!

Link para o comentário
Compartilhar em outros sites

  • Membros Pro

Olá Diego,

A sua resposta faz muito sentido sim! Seria uma alternativa para usar uma DLL, porém segue abaixo os resultados (em vermelho):


// Carregando a DLL dinamicamente
hDll := LoadLibrary("ACBrConsultaCNPJ32.dll")
// OK, carregou a DLL, retornando hDll = 0x03410000

// Verificando se a DLL foi carregada corretamente
IF hDll <> 0
   // Obtendo um ponteiro para a função CNPJ_Consultar
   @CNPJ_Consultar := GetProcAddress(hDll, "CNPJ_Consultar")
 

   // Chamando a função como de costume
   LOCAL resultado, resposta, tamanhoResposta // definido no inicio da função
   tamanhoResposta := 256
   resposta := Space(tamanhoResposta)

   resultado := CNPJ_Consultar("12345678901234", 1, @resposta, @tamanhoResposta)
   

   // Trabalhando com a resposta
   ? "Resultado da consulta:", resultado
   ? "Resposta da consulta:", resposta

   // Fechando a DLL
   FreeLibrary(hDll)
ELSE
   ? "Erro ao carregar a DLL"
ENDIF

Enfim Diego, eu imaginava que iria funcionar, mas continuou não retornando nada na variável resposta.

Agradeço muitooo o empenho de todos, mesmo este tipo de problema não fazendo parte do suporte. 

Caso vocês queiram continuar tentando (pois eventualmente possa ajudar algum outro usuário), vou testar todas as sugestões levantadas, porém caso queiram parar por aqui, eu já fico muito grato pela ajuda.

Mesmo não sendo uma solução "elegante", ler o resultado do LOG resolve o meu problema e já consigo usar a LIB.

Mais uma vez, muito obrigado pelas horas dedicadas a tentar resolver meu problema.

Sergio

 

 

 

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

  • Membros Pro

Olá,

Só complementando os testes, na resposta anterior, após publicar, muitos dos comentários que coloquei sumiram ! 

Também inclui outra variável para iniciar a LIB (declarei antes de CNPJ_Consultar:

CNPJ_Inicializar := GetProcAddress(hDll, "CNPJ_Inicializar") // OK CNPJ_Inicializar = 0x03417CA0

CNPJ_Consultar := GetProcAddress(hDll, "CNPJ_Consultar") // OK CNPJ_Consultar = 0x03417E90

Definindo resposta := '' ou resposta := space(tamanhoResposta) o resultado era o mesmo: resposta = '' ou resposta = space(256)

Tentei também definir a variável resposta como tipo PSZ, e antes de exibir o retorno, transformar em string (defini como PSZ também na definição da função da LIB)

Só que após incluir a inicialização (CNPJ_Inicializar), o log não esta mais exibindo o retorno e na linha "SetRetorno" aparece um caractere "diferente":

17/01/24 06:51:00:469 - TLibConsultaCNPJConfig.AplicarConfiguracoes: c:\sistemas\CoPg_Soares\ACBrLib.ini
17/01/24 06:51:00:470 - TLibConsultaCNPJConfig.Gravar: c:\sistemas\CoPg_Soares\ACBrLib.ini
17/01/24 06:51:00:471 - TLibConsultaCNPJConfig.Gravar - Feito
17/01/24 06:51:00:471 - TLibConsultaCNPJConfig.AplicarConfiguracoes - Feito
17/01/24 06:51:00:471 - TLibConsultaCNPJConfig.Ler - Feito
17/01/24 06:51:00:471 - LIB_Inicializar( ACBrLib.ini,  )
17/01/24 06:51:00:471 -    ACBrLibConsultaCNPJ - 0.0.0.38
17/01/24 06:51:16:708 - CNPJ_Consultar ( 13397985000182,2 )
17/01/24 06:51:16:709 - Travar
17/01/24 06:51:17:018 - Destravar
17/01/24 06:51:17:018 -    MoverStringParaPChar. StrLen:607, BufLen:256
17/01/24 06:51:17:020 -    SetRetorno(0, [Consult_)
17/01/24 06:55:18:354 - TLibConsultaCNPJConfig.AplicarConfiguracoes: c:\sistemas\CoPg_Soares\ACBrLib.ini
17/01/24 06:55:18:354 - TLibConsultaCNPJConfig.Gravar: c:\sistemas\CoPg_Soares\ACBrLib.ini
17/01/24 06:55:18:355 - TLibConsultaCNPJConfig.Gravar - Feito
17/01/24 06:55:18:356 - TLibConsultaCNPJConfig.AplicarConfiguracoes - Feito
17/01/24 06:55:18:356 - TLibConsultaCNPJConfig.Ler - Feito
17/01/24 06:55:18:356 - LIB_Inicializar( ACBrLib.ini,  )
17/01/24 06:55:18:356 -    ACBrLibConsultaCNPJ - 0.0.0.38
17/01/24 06:55:22:067 - CNPJ_Consultar ( 13397985000182,2 )
17/01/24 06:55:22:067 - Travar
17/01/24 06:55:22:318 - Destravar
17/01/24 06:55:22:319 -    MoverStringParaPChar. StrLen:607, BufLen:607
17/01/24 06:55:22:319 -    SetRetorno(0, [Con_)

Bom, vou continuar os testes aqui.

Sergio

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

  • Membros Pro

Boa tarde Renato,

Vou montar uma VM, instalar o Visual Object e carregar um programa teste.

A VM pode ser o VirtualBox? 

Com certeza o interesse é meu (para poder usar todos os recursos das LIBs do ACBr), porém só me aguardem um pouco, pois entre hoje e amanha não sei se consigo te mandar, mas na sexta no máximo eu envio o link para vocês baixarem.

Mais uma vez, muito obrigado pelo esforço em me ajudar.

Sergio

Link para o comentário
Compartilhar em outros sites

  • Consultores

Legal, pode ser VirtualBox sem problemas.

Não tenha pressa, pois também não posso lhe garantir uma resposta imediata quando estiver disponível.

Isso não faz parte do escopo de atendimento do PRO, mas tenho interesse pessoal e acadêmico e farei os testes quando possível em meu tempo livre.

Link para o comentário
Compartilhar em outros sites

  • Membros Pro

Ok Renato,

Como comentei numa mensagem anterior, tenho ciência que este tipo de suporte não faz parte do atendimento e agradeço muito o esforço.

Já vi aqui que eu tenho uma VM de W7 montada. Só vou fazer uma instalação limpa do Visual Object e dos demais arquivos necessários.

Ate mais.

Sergio

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

  • Consultores

Bom dia.

Movi o tópico para a área aberta.

Assim, mais membro da comunidade podem interagir e ajudar.

Consultor SAC ACBr

Diego Folieni
Ajude o Projeto ACBr crescer - Assine o SAC

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

Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil


Participe de nosso canal no Discord e fique ainda mais próximo da Comunidade !!

Link para o comentário
Compartilhar em outros sites

  • Consultores

Boa noite Sérgio,

Não consegui muita coisa ainda, mas aparentemente está ocorrendo alguma exceção silenciosa ao executar o método da dll, não é certeza pois não interrompeu a sequência do debug.

Farei mais testes assim que possível.

A variável de retorno está ficando em branco, mas o que verifiquei é que todas as variáveis do contexto ficaram em branco após a chamada do método.

Talvez você consiga utilizar um try..catch na chamada da função para verificar se muda pelo menos este comportamento de zerar todas as variáveis após a execução do método ou se consegue capturar algum tipo de exceção que ajude a buscar a solução.

Exemplo:

Se você declarar e alimentar qualquer variável antes de chamar o método, ela estará em branco após chamá-lo, mesmo que ela não seja utilizada pelo método.

LOCAL V_Teste AS STRING

V_Teste := 'teste antes'

V_Retorno := CNPJ_Consultar('12345678000195',2,@V_Dados,@V_Tamanho)

// Verifique neste momento o conteúdo de V_Teste, que estará em branco mas deveria conter 'teste antes'.

Conclusão:

Por enquanto, verifique se consegue identificar o que ocorre na chamada do método, que está zerando todas as variáveis, pois é possível que com isso resolva todo o problema.

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

  • Membros Pro

Bom Dia Renato,

Eu tinha notado isto, que antes da chamada da função a variável V_tamanho estava definida com um valor e depois de chamar o método ela volta sem valor nenhum.

Vou tentar fazer isto que vc comentou, criar uma variável qualquer antes do método e ver se muda algo e posto aqui.

Obrigado,

 

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

  • Membros Pro

Oi Renato,

Fiz o teste que sugeriu.

Defini uma variável com um conteúdo qualquer e depois de chamar o método, o conteúdo dela ficou em branco, mesmo ela não tendo nada a ver com o método!

Estou vendo aqui como capturar e exibir os erros e assim que conseguir eu retorno.

Obrigado,

Sergio

 

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

  • Consultores

Boa tarde Sérgio,

Para mim aconteceu o mesmo por isso passei o exemplo para você, consegui debugar com o cenário que você passou, só foi necessário reindexar.

29 minutos atrás, Delfos Sistemas disse:

Estou vendo aqui como capturar e exibir os erros e assim que conseguir eu retorno.

Isso, não encontrei como fazer o try..catch para eventualmente capturar algum erro que ajude a descobrir o motivo.

Mais um teste para você fazer, você disse que já usava a biblioteca para enviar e-mail. Veja se ela também causa esse erro de zerar todas as variáveis.

Link para o comentário
Compartilhar em outros sites

  • Membros Pro

Oi Renato,

Criei novamente uma variável string, com o conteúdo qualquer e fui executando cada método (MAIL_Inicializar, MAIL_Clear, MAIL_ConfigLer, MAIL_ConfigGravarValor, MAIL_ConfigGravar, MAIL_AddAddress, MAIL_SetSubject, MAIL_AddAltBody, MAIL_Send, MAIL_Finalizar) para envio do email e testando o conteúdo da variável.

Para enviar email, o conteúdo da variável não foi zerado em nenhuma situação e no final continuou com o mesmo conteúdo que foi definido.

O problema mesmo é quando o método retorna algum valor para alguma variável.

Estou num cliente e por isto não consegui pesquisar como capturar os erros, mas com certeza deve ter uma forma e vou postar aqui assim que conseguir.

obrigado,

Sergio

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

  • Membros Pro

Oi Renato,

Fiz um outro teste:

Defini a variável que recebe os dados e do tamanho do retorno não como local mas como global (para ser vista em toda a aplicação) e ai o teste anterior de criar uma variável qualquer não alterou o valor mesmo depois de executar o método.

A variável do tamanho que antes do método foi definida como 1000, retornou com o tamanho correto, 607.

Vou fazer mais testes e depois informo.

Sergio

 

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está agora fechado para novas respostas
×
×
  • 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.