Ir para conteúdo
Fórum Script Brasil
  • 0

como faço pra usar essa função que estar na DLL?


vms

Pergunta

ola pessoal

estou com uma duvida com essa função na DLL

consigo compilar a DLL normalmente, mas quando uso no projeto, dar erro

como faço pra usar essa função que estar na DLL?

abaixo estar o codigo completo como estou fazendo, onde estar o erro?

isso é a função na DLL

library DllDelphi;

uses
  Windows, Messages;

function Encrypt( Senha:String ): String;  export;
Const
  Chave : String = 'Jesus';
Var
  x,y : Integer;
  NovaSenha : String;
begin
  for x := 1 to Length( Chave ) do begin
  NovaSenha := '';
  for y := 1 to Length( Senha ) do
  NovaSenha := NovaSenha + chr( (Ord(Chave[x]) xor Ord(Senha[y])));
  Senha := NovaSenha;
  end;
  result := Senha;
end;
exports Encrypt;

begin
end.
isso é projeto que chama a DLL.
unit UProjectDelphi;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button4: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    procedure Button4Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  procedure Encrypt( Senha:String ); external 'DllDelphi.dll'

implementation

{$R *.dfm}

procedure TForm1.Button4Click(Sender: TObject);
begin
  Edit1.Text := Encrypt(Edit1.Text);
end;

end.

Link para o comentário
Compartilhar em outros sites

9 respostass a esta questão

Posts Recomendados

  • 0

valeu pela dica ZueRa, mas eu já tinha visto aqueles post e alguns outros

já consegui fazer algumas coisas com DLL, mas o problema que tenho agora é com essa função que eu citei.

não estou conseguindo usar.

voce pode me ajudar?

Link para o comentário
Compartilhar em outros sites

  • 0
consigo compilar a DLL normalmente, mas quando uso no projeto, dar erro

Não adianta falar que dá erro se voce não posta o erro. Fica mais facil ajudar se souberem qual é o erro.

Coloque o erro exatamente como ele aparece na tela

abraço

Link para o comentário
Compartilhar em outros sites

  • 0
valeu pela dica ZueRa, mas eu já tinha visto aqueles post e alguns outros

já consegui fazer algumas coisas com DLL, mas o problema que tenho agora é com essa função que eu citei.

não estou conseguindo usar.

voce pode me ajudar?

Não sei se posso até saber qual o erro rs

como o amigo Jhonas disse, poste ele para vermos.

Link para o comentário
Compartilhar em outros sites

  • 0

beleza.

tentei fazer de 2 formas, 1 foi assim

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit1.Text := Encrypt(Edit2.Text);
end;
nem compila e dar esse erro:
[Error]UProjectDelphi.pas(31): Incompatible types: 'String' and 'procedure, untyped pointer or untyped parameter'
e tentei assim
procedure TForm1.Button4Click(Sender: TObject);
var
vari : String;
begin
vari := 'valdenir';
Encrypt(vari);
Edit1.Text := vari;
end;

ele compila, mas quando clico no botão dar esse erro:

---------------------------

Debugger Exception Notification

---------------------------

Project ProjectDelphi.exe raised exception class EAccessViolation with message 'Access violation at address 00323010 in module 'DllDelphi.dll'. Write of address 00000000'. Process stopped. Use Step or Run to continue.

---------------------------

OK Help

---------------------------

Link para o comentário
Compartilhar em outros sites

  • 0
[Error]UProjectDelphi.pas(31): Incompatible types: 'String' and 'procedure, untyped pointer or untyped parameter'

Olá vms, boa noite.

O que está acontecendo neste erro é que ele está detectando tipos incompatíveis.

Tente declarar a dll assim:

function Encrypt(Senha:String); stdcall; external 'DllDelphi.dll';

abraço.

P.S: não sei se vai dar certo.

Editado por ZueRa
Link para o comentário
Compartilhar em outros sites

  • 0

Quando voce cria uma DLL, voce verá este aviso

library Project2;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SysUtils,
  Classes;

{$R *.RES}

begin
end.
voce não atentou para este detalhe To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. Na passagem de parametros deve-se usar PChar ou ShortString Então voce deveria fazer assim
procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit1.Text := Encrypt(PChar(Edit2.Text));
end;

Veja um exemplo melhor neste post

http://scriptbrasil.com.br/forum/index.php...st&p=472711

Abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Opa...

Só uma citação...

Você está retornando um ponteiro como uma variável...

PChars "não são" strings, PChars são ponteiros de Char (^Char), nada mais que isto e nesse caso requer

um cuidado especial...

Uma função em uma DLL jamais deve retornar funções do tipo PChar...

Da forma em que está fazendo, quem está alocando o Result é a DLL mas quem está "limpando" da memória?

Quando a DLL é descarregada, seja você chamando em tempo de execução (Run-Time) ou internamente da forma que

está fazendo, no FreeLibrary(handle da DLL) a DLL não faz o trabalho de remover da memória o que foi alocado e no mínimo

você terá um Access Violation, talvez não agora, talvez algumas vezes, vai variar de acordo como a memória está sendo processada

Por isso existe, New(), AllocMem(), FreeMem(), StrDispose()... etc quando se chama um PChar internamente em um .exe

Um artigo muito bom, só que em inglês...

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

Sinceramente, você está tendo sorte que não está tendo Access Violation, mas como disse, com certeza ele vai aparecer bonito pra você hehe

O que você pode fazer é, usar ShortStrings ou fazer como o Windows faz, primeiro saber o tamanho da memória que precisa ser alocada (Buffer),

alocar memória suficiente e depois preencher o Buffer como exemplo no seu caso...

(* DLL *)

uses
  Windows,
  SysUtils,

function Chave(lpBuffer: PChar; var iBuffSize: Integer): BOOL; StdCall;
var
  szBuff: String;
begin
  Result := False;

  //Se a variavel para armazenarmos o tamanho do buffer não foi passada
  //então paramos por aqui
  if @iBuffSize = nil then
  Exit;

  //aqui voce armazena o resultado
  szBuff := 'Delphi';

  //se a variavel para alocar o buffer não foi passada ou o tamanho do
  //buffer que o caller alocou não for suficiente, então
  if (lpBuffer = nil) or (iBuffSize <= Length(szBuff)) then
  //retorna o tamanho do buffer necessario
  iBuffSize := Length(szBuff) + 1 else
  //caso contrario, preenche o buffer com o resultado
  StrLCopy(lpBuffer, PChar(szBuff), iBuffSize - 1);

  Result := True;
end;

exports
  Chave name 'Chave';

(* EXE *)

function Chave: String;
type
  TChaveFunc = record
    hLib: THandle;
    Func: function (lpBuffer: PChar; var iBuffSize: Integer): BOOL; StdCall;
  end;
var
  ChaveFunc: TChaveFunc;
  iLen: Integer;
begin
  Result := '';

  with ChaveFunc do
  begin
    //carrega a DLL
    hLib := LoadLibrary('NOME_DA_DLL.dll');

    //se foi carregada então
    if (hLib <> 0) then
    begin
      //procura a funcao Chave
      @Func := GetProcAddress(hLib, 'Chave');
      //se encontrou então
      if Assigned(Func) then
      //pegamos primeiro o tamanho do buffer necessario, que será retornado
      //na variável: iLen
      if Func(nil, iLen) then
      begin
        //se tudo ok, armazenamos internamente a alocação necessária - 1 referente
        //ao delimitador #0
        SetLength(Result, iLen - 1);
        //com o tamanho do buffer já correto e a alocação feita, buscamos o
        //resultado
        Func(PChar(Result), iLen);
      end;
      //trata o resultado corretamente, pode se usar também StrPas();
      Result := PChar(Result);

      //Liberamos a DLL da memória
      FreeLibrary(hLib);
    end;
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(Chave);
end;

é bem mais complicado, mas te garanto, nesse caso é a maneira correta...

Procure em Windows.pas ou qualquer código fonte que manipule PChar em DLL, você não vai ver uma função na DLL retornar PChar

Já tive muitosss problemas com isso e depois de apanhar muitooo e tal que aprendi hehe

abrs

Editado por Churc
Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,2k
×
×
  • Criar Novo...