Ir para conteúdo
  • Cadastre-se

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

Recommended Posts

Postado

Bom dia Galera isso aqui é mais uma auxilio eu queria colocar um exemplo de código meu que eu fiz em deno com AcbrLib

"loader.ts"

/*
    Essa biblitoeca é responsável pela comunicação com a
    ACBrLib.
*/


import * as path from "jsr:@std/path";

export const libSymbols = {
    NFSE_Inicializar: { parameters: ["buffer", "buffer"], result: "i32" },
    NFSE_Finalizar: { parameters: [], result: "i32" },
    NFSE_ConfigGravarValor: { parameters: ["buffer", "buffer", "buffer"], result: "i32"},
    NFSE_ConfigLerValor: { parameters: ["buffer", "buffer", "buffer", "buffer"], result: "i32"},
    NFSE_ConfigGravar: {parameters: [ "buffer"], result: "i32"},
    NFSE_UltimoRetorno: { parameters: ["buffer", "buffer"], result: "i32" },
    NFSE_CarregarINI: { parameters: ["buffer"], result: "i32" },
    NFSE_CarregarXML: { parameters: ["buffer"], result: "i32" },
    NFSE_ObterXml: { parameters: ["i32", "buffer", "buffer"], result: "i32"},
    NFSE_ObterIni: { parameters: ["i32", "buffer", "buffer"], result: "i32"},
    NFSE_ObterXmlRps: { parameters: ["i32", "buffer", "buffer"], result: "i32"},
    NFSE_LimparLista: { parameters: [], result: "i32" },
    NFSE_Emitir: { parameters: ["buffer", "i32", "i32", "buffer", "buffer"], result: "i32" }
} as const satisfies Deno.ForeignLibraryInterface; 

type typLibNFSe = typeof libSymbols;

class loadlibNFSe{
    static init() {
        //Métodos da Biblioteca
        const __prefixDir : string = path.dirname(path.fromFileUrl(import.meta.url)) as string
        const libPath = path.join(__prefixDir, 'libnfse.so')
        const NFSE = Deno.dlopen(libPath, libSymbols);
        return NFSE;
    }
}

export { loadlibNFSe };
export type { typLibNFSe };

"fiscalModulo.ts"
 

import * as path from "jsr:@std/path";


// ACBr FFI
import { loadlibNFSe, typLibNFSe }  from "./NFSe_ACBrLib/loader.ts"

const __prefixDir : string = path.dirname(path.fromFileUrl(import.meta.url)) as string

class controleFiscal {
    CONFIG_INI = path.resolve(__prefixDir, 'config.ini');
    NFSE: Deno.DynamicLibrary<typLibNFSe> = loadlibNFSe.init();
    init(){
        /*  
            Inicia as Bibliotecas, esse metodo só pode ser acionado
            uma unica vez.
        */
        
        this.initNFSe();
        this.initConfig();

        return this;
    }

    initNFSe(){
        /*
            inicia a configuração da Lib ACbre NFE
        */
        // this.NFSE = loadlibNFSe.init();
        this.NFSE.symbols.NFSE_LimparLista();
                
        const ret : number = this.NFSE.symbols.NFSE_Inicializar(
            this.txt(this.CONFIG_INI),
            this.txt("")
        )

        if(ret != 0){
          throw Error("não foi possível iniciar a bilbioteca NFe")          
        }

    }
   
    initConfig(){
        /*
            Efetua as configurações iniciais que definem boa
            parte do funcionamento da bibliote Acbr.
        */
        const pathLog = path.resolve(Deno.cwd(), 'log')
        const ambiente = String(Number((Deno.env.get("AMBIENTE_SEFAZ")!)) -1)

        // // Esquemas de XML
        // const pathEsquemaNFe = path.resolve(__prefixDir, 'NFe_ACBrLib', 'Schemas')
        // const pathEsquemaMDFe = path.resolve(__prefixDir, 'MDFe_ACBrLib', 'Schemas')
        const pathEsquemaNFSe = path.resolve(__prefixDir, 'NFSe_ACBrLib', 'Schemas')
        // const pathEsquemaCTe = path.resolve(__prefixDir, 'CTe_ACBrLib', 'Schemas')
        
        // // Arquivo de Urls do Serviço
        // const path_nf_ser = path.join(path.resolve(__prefixDir, 'NFe_ACBrLib'), 'ACBrNFeServicos.ini')
        // const path_mdfe_ser = path.join(path.resolve(__prefixDir, 'MDFe_ACBrLib'), 'ACBrMDFeServicos.ini')
        const path_nfse_ser = path.join(path.resolve(__prefixDir, 'NFSe_ACBrLib'), 'ACBrNFSeServicos.ini')
        // const path_cte_ser = path.join(path.resolve(__prefixDir, 'CTe_ACBrLib'), 'ACBrCTeServicos.ini')

        // // Resposta do Tipo INI para evitar problemas com conversão XML
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("Principal"), this.txt("TipoResposta"), this.txt("0"))
        // // Codificação UTF - 8
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("Principal"), this.txt("CodificacaoResposta"), this.txt("0"))
        
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("Principal"), this.txt("LogNivel"), this.txt("4")) // 4 retorno total
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("Principal"), this.txt("LogPath"), this.txt(pathLog))

        // // Informações referentes ao sistema & SoftHouse
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("Sistema"), this.txt("Nome"), this.txt("DH CONSULTING - HERA"))
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("Sistema"), this.txt("Versao"), this.txt("0.1"))
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("Sistema"), this.txt("Descricao"), this.txt("Versão de Beta, Em Desenvolvimento"))

        // // Prenchimento referente a biblioteca NFE
        // // https://acbr.sourceforge.io/ACBrLib/ConfiguracoesdaBiblioteca16.html
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("NFe"), this.txt("FormaEmissao"), this.txt(Deno.env.get("AMB_EMI_NFE") || "0"))
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("NFe"), this.txt("SalvarGer"), this.txt("0"))
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("NFe"), this.txt("ExibirErroSchema"), this.txt("1"))
        // // Problemas de SSL geralmente estão relacionados a essa configuração
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("NFe"), this.txt("SSLType"), this.txt("5")) 
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("NFe"), this.txt("PathSchemas"), this.txt(pathEsquemaNFe))        
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("NFe"), this.txt("IniServicos"), this.txt(path_nf_ser))
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("NFe"), this.txt("SalvarArq"), this.txt("0"))
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("NFe"), this.txt("Ambiente"), this.txt(ambiente))
        // // Desabilita o Digvalue para consulta
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("NFe"), this.txt("ValidarDigest"), this.txt("0"))

        // // Carregar Certificado
        // // https://acbr.sourceforge.io/ACBrLib/DFe.html
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("DFe"), this.txt("SSLCryptLib"), this.txt("1"))
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("DFe"), this.txt("UF"), this.txt(Deno.env.get("UF_EMIT") || ""))
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("DFe"), this.txt("SSLHttpLib"), this.txt("3"))
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("DFe"), this.txt("SSLXmlSignLib"), this.txt("4"))
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("DFe"), this.txt("TimeZone.Modo"), this.txt("2"))
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("DFe"), this.txt("TimeZone.Str"), this.txt("-03:00"))

        // //DANFe
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("DANFENFe"), this.txt("ExpandirDadosAdicionaisAuto"), this.txt("1"))
        // this.NFE.symbols.NFE_ConfigGravarValor(this.txt("DANFENFe"), this.txt("LarguraCodProd"), this.txt("100"))
        // this.NFE.symbols.NFE_ConfigGravar(this.txt(this.CONFIG_INI));
                
        // //this.CTE.symbols.CTE_ConfigGravarValor(this.txt("CTe"), this.txt("FormaEmissao"), this.txt("0"))
        // this.CTE.symbols.CTE_ConfigGravarValor(this.txt("CTE"), this.txt("SalvarGer"), this.txt("0"))
        // this.CTE.symbols.CTE_ConfigGravarValor(this.txt("CTE"), this.txt("ExibirErroSchema"), this.txt("1"))
        // this.CTE.symbols.CTE_ConfigGravarValor(this.txt("CTE"), this.txt("SSLType"), this.txt("5")) 
        // this.CTE.symbols.CTE_ConfigGravarValor(this.txt("CTE"), this.txt('PathSchemas'), this.txt(pathEsquemaCTe))
        // this.CTE.symbols.CTE_ConfigGravarValor(this.txt("CTE"), this.txt('IniServicos'), this.txt(path_cte_ser))
        // this.CTE.symbols.CTE_ConfigGravarValor(this.txt("CTE"), this.txt("SalvarArq"), this.txt("0"))
        // this.CTE.symbols.CTE_ConfigGravarValor(this.txt("CTE"), this.txt("Ambiente"), this.txt(ambiente))
        // this.CTE.symbols.CTE_ConfigGravar(this.txt(this.CONFIG_INI));

        // Prenchimento referente a biblioteca NFSe
        // https://acbr.sourceforge.io/ACBrLib/ConfiguracoesdaBiblioteca22.html
        //this.NFSE.symbols.NFSE_ConfigGravarValor(this.txt("NFSe"), this.txt("FormaEmissao"), this.txt("0"))
        this.NFSE.symbols.NFSE_ConfigGravarValor(this.txt("NFSe"), this.txt("SalvarGer"), this.txt("0"))
        this.NFSE.symbols.NFSE_ConfigGravarValor(this.txt("NFSe"), this.txt("ExibirErroSchema"), this.txt("1"))
        this.NFSE.symbols.NFSE_ConfigGravarValor(this.txt("NFSe"), this.txt("SSLType"), this.txt("5"))
        this.NFSE.symbols.NFSE_ConfigGravarValor(this.txt("NFSe"), this.txt("PathSchemas"), this.txt(pathEsquemaNFSe))
        this.NFSE.symbols.NFSE_ConfigGravarValor(this.txt("NFSe"), this.txt("IniServicos"), this.txt(path_nfse_ser))
        this.NFSE.symbols.NFSE_ConfigGravarValor(this.txt("NFSe"), this.txt("SalvarArq"), this.txt("0"))
        this.NFSE.symbols.NFSE_ConfigGravarValor(this.txt("NFSe"), this.txt("Ambiente"), this.txt(ambiente))
        this.NFSE.symbols.NFSE_ConfigGravar(this.txt(this.CONFIG_INI));

        // // Prenchimento referente a biblioteca MDFe
        // // https://acbr.sourceforge.io/ACBrLib/ConfiguracoesdaBiblioteca14.html
        // //this.MDFE.symbols.MDFE_ConfigGravarValor(this.txt("MDFe"), this.txt("FormaEmissao"), this.txt("0"))
        // this.MDFE.symbols.MDFE_ConfigGravarValor(this.txt("MDFe"), this.txt("SalvarGer"), this.txt("0"))
        // this.MDFE.symbols.MDFE_ConfigGravarValor(this.txt("MDFe"), this.txt("ExibirErroSchema"), this.txt("1"))
        // this.MDFE.symbols.MDFE_ConfigGravarValor(this.txt("MDFe"), this.txt("SSLType"), this.txt("5")) 
        // this.MDFE.symbols.MDFE_ConfigGravarValor(this.txt("MDFe"), this.txt('PathSchemas'), this.txt(pathEsquemaMDFe))
        // this.MDFE.symbols.MDFE_ConfigGravarValor(this.txt("MDFe"), this.txt('IniServicos'), this.txt(path_mdfe_ser))
        // this.MDFE.symbols.MDFE_ConfigGravarValor(this.txt("MDFe"), this.txt("SalvarArq"), this.txt("0"))
        // this.MDFE.symbols.MDFE_ConfigGravarValor(this.txt("MDFe"), this.txt("Ambiente"), this.txt(ambiente))
        // this.MDFE.symbols.MDFE_ConfigGravar(this.txt(this.CONFIG_INI));

        // // Congigurações do Email
        // // https://acbr.sourceforge.io/ACBrLib/Geral.html
        // this.MAIL.symbols.MAIL_ConfigGravarValor(this.txt("Email"), this.txt("Nome"), this.txt("HERA Messageria"))
        // this.MAIL.symbols.MAIL_ConfigGravarValor(this.txt("Email"), this.txt("Servidor"), this.txt(Deno.env.get("EMAIL_SERVIDOR") || ""))
        // this.MAIL.symbols.MAIL_ConfigGravarValor(this.txt("Email"), this.txt("Conta"), this.txt(Deno.env.get("EMAIL_ENDERECO") || ""))
        // this.MAIL.symbols.MAIL_ConfigGravarValor(this.txt("Email"), this.txt("Usuario"), this.txt(Deno.env.get("EMAIL_USUARIO") || ""))
        // this.MAIL.symbols.MAIL_ConfigGravarValor(this.txt("Email"), this.txt("Senha"), this.txt(Deno.env.get("EMAIL_SENHA") || ""))
        // this.MAIL.symbols.MAIL_ConfigGravarValor(this.txt("Email"), this.txt("Porta"), this.txt(Deno.env.get("EMAIL_PORTA") || ""))
        // this.MAIL.symbols.MAIL_ConfigGravarValor(this.txt("Email"), this.txt("SSL"), this.txt(Deno.env.get("EMAIL_SSL") || ""))
        // this.MAIL.symbols.MAIL_ConfigGravarValor(this.txt("Email"), this.txt("TLS"), this.txt(Deno.env.get("EMAIL_TLS") || ""))
        // this.MAIL.symbols.MAIL_ConfigGravarValor(this.txt("Email"), this.txt("IsHTML"), this.txt("1"))
        // this.MAIL.symbols.MAIL_ConfigGravarValor(this.txt("Email"), this.txt("SegundoPlano"), this.txt("0"))
        // this.MAIL.symbols.MAIL_ConfigGravarValor(this.txt("Email"), this.txt("SSLType"), this.txt(Deno.env.get("EMAIL_SSLTYPE") || ""))
        // this.MAIL.symbols.MAIL_ConfigGravar(this.txt(this.CONFIG_INI));
    }

    ptrDinamicCall(libName: string, method: string = "NFE_ObterXml", params: Array<number | string | Uint8Array> = []){
        /*
            -  Metodo de chamada dinamica para funções com passagem
            de parametro de string

            os parametros de String ponteiro e int Ponteiro sempre são os 
            ultimos

            Args:
                Parms:
                    - libName: o atributo lib a ser chamada como (NFE e MDFE)
                    - method: qual metodo do lib vai ser chamada
                    - params: os parametros passados tirando sResposta e esTamanho.

                Return: retornará a string já convertida de sResposta
        */
        // por segurança para o metodo para uper case
        libName = libName.toUpperCase();

        // faz a conversão de parametros (se necessário)
        const args = [ ]
        params.forEach(param => {
            switch(typeof param){
                case "string":
                    args.push(this.enc.encode(param + '\0'))
                    break;
                default:
                    args.push(param)
            }
        });       

        const DEFAULT_LENGTH = 2792; // Tem que ser divisivel por 8
        const outPtrs = new ArrayBuffer(8 + DEFAULT_LENGTH); // A soma deve dar um valor sem 0 na casa decimal final?
        const sResposta = new Uint8Array(outPtrs, 8, DEFAULT_LENGTH);
        const esTamanho = new Uint8Array(outPtrs, 0, 8);
        // aloca o valor default para os espaço tamanho do buffer
        const esTamanhoView = new Uint16Array(outPtrs, 0, 4); 
        esTamanhoView[0] = DEFAULT_LENGTH;

        args.push(sResposta)
        args.push(esTamanho)

        type typSymbolFFICall = { symbols : { [Key: string]: CallableFunction } }
        
        const libModule = this[libName as keyof controleFiscal] as typSymbolFFICall;
        if(libModule!.symbols[method](...args) == 0){
            // Algo deu errado
            const esTamanhoValue = esTamanhoView[0];
            if (esTamanhoValue > DEFAULT_LENGTH) {
                // a Biblioteca Precisa de mais memoria 
                // NOTA: supeito que apesar de es  tamanho estar em outro buffer
                // ele precisa desse +64 bits para contablizar o ponteiro de estamanho
                // sem esse +8 a bilbioteca gera erros como "maloc sized"
                const realloc = new Uint8Array(esTamanhoValue + 8); 
                libModule.symbols[`${libName}_UltimoRetorno`](realloc, esTamanho);
                return new TextDecoder().decode(realloc);
            } else {
                return new TextDecoder().decode(sResposta.subarray(0, esTamanhoValue));
            }
        }else{
            return ""; // Sem dados
        }
    }

    ambienteEmissao(libName: string, ambiente: string){
        // Define o ambiente de Envio
        // # Sefaz
        // 1 Produção       2 - Homologação
        // # ACBrLib
        // 0 - Produção     1 - Homologação
        type typSymbolFFICall = { symbols : { [Key: string]: CallableFunction } }

        const tpAmb: string = (ambiente == "1" ? "0" : "1");

        // Caso o tipo seja o mesmo não será necessário alterar
        if (tpAmb != this.ptrDinamicCall(
            libName, 
            `${libName.toUpperCase()}_ConfigLerValor`, 
            [this.txt(libName), this.txt("Ambiente")]
        )){    
            const libModule = this?.[libName.toUpperCase() as keyof controleFiscal] as typSymbolFFICall;

            libModule.symbols[`${libName.toUpperCase()}_ConfigGravarValor`](this.txt(libName), this.txt("Ambiente"), this.txt(tpAmb))
            libModule.symbols[`${libName.toUpperCase()}_ConfigGravar`](this.txt(this.CONFIG_INI));
        }
    }

    /* converte string para o formato que FFI da chamada da bilvioteca entenda */
    private enc = new TextEncoder()
    txt = (txt : string) => this.enc.encode(txt + '\0')
}

export { controleFiscal };

"main.ts"

import { controleFiscal } from './fiscalModulo.ts'


async function main() {
    const ctl = new controleFiscal().init();
    // Teste de Criação    
    ctl.NFSE.symbols.NFSE_LimparLista();
    
    ctl.NFSE.symbols.NFSE_CarregarINI(ctl.txt('./NFSE_CREATE.ini'));
    const xml = ctl.ptrDinamicCall(
        "NFSE",
        "NFSE_ObterXml"
        [0]
    )

    ctl.ptrDinamicCall(
        "NFSE",
        "NFSE_ObterXml"
        [0]
    )
}

main;

aqui deixo uma referencia que pode ser util para parametrização, 
Foreign Function Interface (FFI)
o método ptrDinamicCall é para facilitar retornar os parâmetros

  • Curtir 2
Postado (editado)
3 minutos atrás, danieloliveira-mm disse:

Boa tarde,

Fizemos classes de alto nível em typescript para nodejs, ela é baseada no koffi

Parece ser compatível 

Lembre-se de adicionar no package.json

"type": "commonjs"

image.png

já usei o koffi em js, mas optei por usar a classe nativa por motivos de desempenho. e estabilitadade ("dependendo da versão do node eu tinha problemas com o KOFFI")

Editado por Caio da DH
  • Este tópico foi criado há 189 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.