Fórum Como declarar função de uma DLL (Delphi) #623688

24/03/2025

0

Boa tarde, tenho uma função numa DLL que retorna diversos valores, então o retorno da função é uma classe, pergunto, como faço o chamado dessa função (que esta na DLL) em outra aplicação, visto que a classe que ela retorna não existe na aplicação?
Estou usando o delphi 7 nesse caso..
Ex:
TMInhaClasse = class
FCod : Integer;
FNome : String;
FSituacao : String;

function RetornaDados(pValor: Integer) : TMinhaClasse; stdcall;
begin
comandos....
result.Cod := ret.codigo;
result.Nome := ret.nome;
result.Situacao := ret.status;
end;

Na aplicação poderia fazer o chamado no método estático:
function RetornaDados(pValor: Integer) : TMinhaClasse; stdcall; external 'Arquivo.DLL'

Mas TMinhaClasse não existe na aplicação, como resolver isso?
Domper Ltda

Domper Ltda

Responder

Posts

24/03/2025

Arthur Heinrich

Eu posso estar falando besteira, mas funções que retornam classes, na realidade retornam a referência para uma instância da classe.

No seu caso, por se tratar de uma DLL, o acesso da aplicação à memória alocada pela DLL eu tenho a impressão de que não é permitido, já que a aplicação e a DLL trabalham em contextos diferentes.

O que normalmente se faz é utilizar funções ou procedures na DLL que fazem a troca das informações através de parâmetros escalares, passados por referência, ou mediante estruturas (record), que é preenchido a partir de um endereço passado.

Uma maneira de tentar resolver é vendo como funciona a API do Windows. Geralmente tem uma estrutura do tipo TProcessInfo (exemplo), que contém informações sobre um processo. Alocamos um buffer com o tamanho desta estrutura e o passamos para a função, que retorna X bytes no buffer alocado.

Algumas funções podem retornar dados de tamanho variado e, aí, precisamos informar o tamanho máximo do buffer e a função retorna o tamanho da informação retornada.

Não parece algo simples.
Responder

Gostei + 0

25/03/2025

Domper Ltda

Bom dia, podemos fazer a função na DLL retornando um record como citou, mas a declaração dessa função na aplicação terá o mesmo problema, afinal o record não existe na aplicação, como resolver isso? teria algum exemplo?
Responder

Gostei + 0

29/03/2025

Arthur Heinrich

O link abaixo descreve bem os problemas de se utilizar DLLs e suas limitações. Acredito que valha a pena dar uma olhada para esclarecer.

http://rvelthuis.de/articles/articles-dlls.html

De acordo com o artigo, é melhor que as functions retornem datatypes simples, como um Inteiro, por exemplo, para indicar se a função foi executada com sucesso (0) ou insucesso (1).

Para retornar estruturas, o melhor jeito é utilizar pointers.

Você declara o mesmo tipo, tanto na DLL como na aplicação. Obviamente, se criar um parâmetro do tipo "var", que passa o parâmetro por referência, vai ter um problema de checagem de datatypes, já que o tipo da DLL e da aplicação não são os mesmos, embora do mesmo tipo.

O que é comum de se fazer é declarar o parâmetro como um ponteiro para a estrutura e passar o endereço.

Exemplo:

Ao invés de fazer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
type
  TEstrutura = record
    Field1 : Integer;
    Field2 : Single;
    end;
 
function Funcao1(var E1 : TEstrutura):Integer;
...
 
var
  Estrutura : TEstrutura;
  Return : Integer;
 
Return := Funcao1(Estrutura);


Você faz:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
type
  TEstrutura = record
    Field1 : Integer;
    Field2 : Single;
    end;
 
function Funcao1(E1 : ^TEstrutura):Integer;
...
 
var
  Estrutura : TEstrutura;
  Return : Integer;
 
Return := Funcao1(@Estrutura);


Dentro da DLL, que vai receber um pointer, a função deve utilizar um cast:

1
2
3
function Funcao1(E1 : ^TEstrutura):Integer;
...
TEstrutura(E1^).Field1 := xxx;


Tem que tomar cuidado com o tipo String do Delphi, que é bem diferente. O Delphi aceita vários modelos de armazenamento para representar strings e podem não representar tipos válidos em outras linguagens.

Este link comenta sobre eles:

https://docwiki.embarcadero.com/RADStudio/Athens/en/String_Types_(Delphi)
Responder

Gostei + 0

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

Aceitar