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

19/01/2024

0

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

Responder

Post mais votado

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'));

Arthur Heinrich

Arthur Heinrich
Responder

Mais Posts

19/01/2024

André Munhoz

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!

Responder

19/01/2024

André Munhoz

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". :(
Responder

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar