Criar método em uma OCX Delphi com retorno em string

HTML

Delphi

JavaScript Web

19/01/2024

Olá pessoal, boa tarde! Se alguém puder me ajudar com esta necessidade, ficarei muito agradecido!

Construí uma OCX em Delphi com diversos métodos de escrita, porém estou agora precisando criar um método que leia uma variável string internamente e devolva o mesmo valor para uma aplicação WEB HTML com JavaScript.

No modo "Design" do arquivo ".ridl" eu criei o método com um parâmetro do tipo VARIANT* e com modificador "out".

Na declaração do arquivo "TLB" eu declarei a função assim:

function NumeroCupon(out Param1: VARIANT): integer; stdcall;

Onde, "Param1" é o parâmetro que irá receber um valor e disponibilizar para a aplicação WEB.

No entanto, quando eu faço o Result deste parâmetro, na aplicação WEB o retorno é "undefined", como se não tivesse exportado nada.

Este é o trecho do código JavaScript:

        function NumeroCupon() {
            try {
                var Par1;
                var resultado = meuActiveX.NumeroCupon(Par1);
                document.getElementById( "numero" ).innerHTML = Par1;                
            } catch (e) {
                alert('Error: ' + e.message);
            }
        }


Este é o trecho do código em Delphi da rotina do método NumeroCupon:

function TBemaFiscOCX.NumeroCupon(out Param1: VARIANT): integer;
var
  BemaFI32DLL: HMODULE;
  Bematech_FI_NumeroCupon: function (Dados: AnsiString): Integer; stdcall;
  numero: AnsiString;
begin
  BemaFI32DLL := LoadLibrary('BemaFI32.dll');
  if BemaFI32DLL <> 0 then
    begin
      @Bematech_FI_NumeroCupon := GetProcAddress(BemaFI32DLL, 'Bematech_FI_NumeroCupon');
      if Assigned(Bematech_FI_NumeroCupon) then
        begin
          numero := StringOfChar(' ', 7);
          Result := Bematech_FI_NumeroSerieMFD(numero);
          Param1 := numero;
        end
      else
        FreeLibrary(BemaFI32DLL);
    end;
end;


Obrigado!
André Munhoz

André Munhoz

Curtidas 0

Melhor post

Arthur Heinrich

Arthur Heinrich

19/01/2024

Sua função possui 2 IFs aninhados, mas só atribui valores à variável Result em uma das 4 situações possíveis.

Se BemaFI32DLL = 0, Result está indefinido.
Se a atribuição "@Bematech_FI_NumeroCupon := GetProcAddress(BemaFI32DLL, 'Bematech_FI_NumeroCupon');" falhar, também tem resultado indefinido.

Esta é uma funcionalidade que, embora eu já tenha utilizado algumas vezes, não é muito comum.

Eu sei que o operador @ é utilizado para retornar o endereço de uma variável. Porém, para atribuir o endereço à variável, não me recordo de ter que utilizar o @.

Talvez você tenha que utilizar apenas: Bematech_FI_NumeroCupon := GetProcAddress(BemaFI32DLL, 'Bematech_FI_NumeroCupon');

O que pode acontecer é de o compilador reclamar do datatype. Pode ser necessário criar o tipo e, depois, utilizá-lo para fazer o cast.

type
  TFunc = function (Dados: AnsiString): Integer; stdcall;
var
  Bematech_FI_NumeroCupon: TFunc;
...
      Bematech_FI_NumeroCupon := TFunc(GetProcAddress(BemaFI32DLL, 'Bematech_FI_NumeroCupon'));

GOSTEI 1

Mais Respostas

André Munhoz

André Munhoz

19/01/2024

Sua função possui 2 IFs aninhados, mas só atribui valores à variável Result em uma das 4 situações possíveis.

Se BemaFI32DLL = 0, Result está indefinido.
Se a atribuição "@Bematech_FI_NumeroCupon := GetProcAddress(BemaFI32DLL, 'Bematech_FI_NumeroCupon');" falhar, também tem resultado indefinido.

Esta é uma funcionalidade que, embora eu já tenha utilizado algumas vezes, não é muito comum.

Eu sei que o operador @ é utilizado para retornar o endereço de uma variável. Porém, para atribuir o endereço à variável, não me recordo de ter que utilizar o @.

Talvez você tenha que utilizar apenas: Bematech_FI_NumeroCupon := GetProcAddress(BemaFI32DLL, 'Bematech_FI_NumeroCupon');

O que pode acontecer é de o compilador reclamar do datatype. Pode ser necessário criar o tipo e, depois, utilizá-lo para fazer o cast.

type
  TFunc = function (Dados: AnsiString): Integer; stdcall;
var
  Bematech_FI_NumeroCupon: TFunc;
...
      Bematech_FI_NumeroCupon := TFunc(GetProcAddress(BemaFI32DLL, 'Bematech_FI_NumeroCupon'));



Oi Arthur, muitíssimo obrigado pelo seu retorno, amigo!

Com relação a este código:

function TBemaFiscOCX.NumeroCupon(out Param1: VARIANT): integer;
var
  BemaFI32DLL: HMODULE;
  Bematech_FI_NumeroCupon: function (Dados: AnsiString): Integer; stdcall;
  numero: AnsiString;
begin
  BemaFI32DLL := LoadLibrary('BemaFI32.dll');
  if BemaFI32DLL <> 0 then
    begin
      @Bematech_FI_NumeroCupon := GetProcAddress(BemaFI32DLL, 'Bematech_FI_NumeroCupon');
      if Assigned(Bematech_FI_NumeroCupon) then
        begin
          numero := StringOfChar(' ', 7);
          Result := Bematech_FI_NumeroCupon(numero);
          Param1 := numero;
        end
      else
        FreeLibrary(BemaFI32DLL);
    end;
end;


A função "Bematech_FI_NumeroCupon" está executando normalmente, pois na variável "numero" vem o retorno que eu preciso, porém não estou conseguindo é exportar esta variável para o JavaScript. Ou seja, eu recebo corretamente o retorno da informação no parâmetro "numero" da função "Bematech_FI_NumeroCupon", mas não está disponibilizando a informação na chamada em JavaScript.

var resultado = meuActiveX.NumeroCupon(Par1);


Eu deveria receber a informação na variável "Par1".

Detalhe: a variável "resultado" retorna certinho o valor "integer" da função "Bematech_FI_NumeroCupon".

Abraços!

GOSTEI 0
André Munhoz

André Munhoz

19/01/2024

Ou até pra ficar mais simplificado.

No arquivo ".ridl" criei o método "MeuNome":

int _stdcall MeuNome([out] VARIANT* Param1);


Na declaração do método:

function MeuNome([out] var Param1: VARIANT): SYSINT; stdcall;


No código de execução deste método:

function TMinhaOCX.MeuNome([out] var Param1: VARIANT): SYSINT; stdcall;
begin
  Param1 := 'Andre';
end;


No código em JavaScript para retornar "Andre":

        function MeuNome() {
            try {
                var Par1;
                var resultado = bematechActiveX.MeuNome(Par1);               

                document.getElementById( "retorno" ).innerHTML = Par1;  

            } catch (e) {
                alert('Error: ' + e.message);
            }
        }


Mas a variável Par1 mostra "undefined". :(
GOSTEI 0
POSTAR