Access variable contained in a BPL

Asked

Viewed 1,256 times

2

I have a system developed in Delphixe3 and I’m starting to modular it. However, another question has arisen. In a Unit that will be in one of the modules, I own:

type 
   TUsuario = record
     id:Integer;
     idEmpresa:Integer;
     usuario:string;
     foto:string;
     validade: TDateTime;
     senha:string;
     nome:string;
     admin:Boolean;
     ultimoAcesso:TDateTime;
     dataCadastro:TDateTime;
   end;

and

var
  usuario:TUsuario;

That at certain times I will feed this variable and in others I will retrieve her information. My question: How to do this?


Updating

My system is distributed as follows:

Aplicação - Menu - Login - Package Default (Runtime Package) * Unit TUsuario * Unit FuncoesDefault * Unit FuncoesSeguranca - Package Cadastros (Carregado via LoadPackage) * CD001 - Uma tela de cadastros qualquer

Regarding the error of Access Violation, I am creating the variable inside the package Default, in Unit Funcoesdefault.

In my application, on the login screen, I instantiate the already created variable:

usuario:= TUsuario.Create;

At the Event FormShow form CD001, I call a Function unit Funcoesseguranca, responsible for checking in the database the rights of the user (insert, edit, remove, etc). This Function receives by parameter a string with the screen code and my variable usuario, previously created on the login screen.

Right in the forefront of my Function there is a if usuario.isAdmin to check if the user is an administrator. I already get the error of Access Violation.


Updating

Follow an excerpt from my Unit Funcoesdefault

unit FuncoesDefault;

interface

uses
  U_TUsuario;

var
  usuario:TUsuario;

implementation

initialization
  usuario := TUsuario.Create;

end.

1 answer

4

First of all, I recommend you abandon the practice of using record and start using class, which is a more modern and much more powerful language construction. To do so, study a little about object-oriented programming, classes, constructor, destructor, methods and properties.

With regard you asked, since the class TUsuario is declared, declare a utility class to operate on these objects, for example TUsuarioRepositorio, which will have a number of methods to recover and save instances of TUsuario. Something like:

type
  TUsuarioRepositorio
  public
    class function UsuarioPorNome(const aNome: string): TUsuario;
    class procedure Salvar(aUsuario: TUsuario);
  end;

so in a certain part of your code you would create a user like this:

var
  novoUsuario: TUsuario;
begin
  ...
  novoUsuario := TUsuario.Create;
  novoUsuario.Nome := 'Huguinho';
  novoUsuario.Senha := 'M@rgar1da';
  novoUsuario.Admin := True;

  TUsuarioRepositorio.Salvar(novoUsuario);
  ...
end;

In this code a class object TUsuario is instantiated, some of its properties are initialized and it is saved somewhere (file or database). Then to recover this same user the code could be:

var
  usuarioProcurado: TUsuario;
  nome: string;
begin
  ...
  nome := 'Huguinho';
  usuarioProcurado := TUsuarioRepositorio.UsuarioPorNome(nome);
  if usuarioProcurado <> nil then
    ShowMessage(Format('O usuário %s tem o Id=%d', [usuarioProcurado.Nome, usuarioProcurado.Id]))
  else
    ShowMessage('Nenhum usuário existe com o nome='+nome); 
  ...
end;

With this work model you separated the object from the code that manipulates the persistence of this object, which is a great practice of programming and design, in addition to allowing a high level of code modularization, as you can place the objects in a package and the repositories in another.

As the idea is modularize you can put the Unit declaring TUsuario (for example, Usuarios.pas) in a package separate. When compiled, the project of this package will generate a file .BPL (for example, SegurancaD17.BPL) and an archive .DCP (SegurancaD17.DCP). The design of this package must be configured to be a Runtime package and the design of your application should indicate at least this as a Runtime package.

On your application it will be enough to do the uses of Unit Usuarios. When compiling your project Delphi will realize that the Unit is in a Runtime package and will generate dependency for it instead of including in the .EXE. When you distribute the .EXE, shall distribute together the SegurancaD17.BPL, the file .DCP is important for the compiler, not the executable.

  • Cool, I already work with OO programming in java, Delphi should not be much different. Assuming then that I have my application only the Menu, the other screens are separated in Bpls. I have a module called security, which has the login screen. When loading the menu, I call the login screen. If you validate the login, I prompt an Object of type Tusuario and continue loading the application.

  • My question, should the Tusuario class be in a Unit within the BPL 'security'? If, at some point I need to access this object of another module, as I should do since it is not in the same module that I am working, but in another?

  • 1

    @Thiagothaison: I added some details to my original reply

  • I created the Tusuario class and included it in a package that is already in the Runtime package of my application, as you suggested. My project looks like this for now: Application -Package Default (Runtime) -Package Register (Loaded via Loadpackage) Inside my application, after logging in, I am creating an object of the Tusuario type (whose declaration is inside a Unit, in pkg Default). When trying to access the properties of this object from within pkg Cadastre, I am receiving an Access Violation error, as if my object had not been created. But he’s already made :(

  • @Thiagothaison: If you didn’t have compilation errors, I assume the Packages is correct. Instantiation is taking place within the application or within one of the Packages? Are you sure you’re accessing the correct variable? Edit your question to include the codes where you instantiate the object and where you try to access it, to make it easier to evaluate the case.

  • I’ve already added the details to my question, as you requested.

  • @Thank you for the details. Considering what you showed, I can only understand that the variable passed to your rights assessment function is not the same one that received the instance of TUsuario. You that variable is instantiated in the login form, but the variable is declared where? It seems to be a global variable, is that right? A simple test to know if the instance is created and is valid is to evaluate the value of the property ClassName (in your case, the value of usuario.ClassName. This property should return a string containing, in your case, <Unit’s name>.TUsuario.

  • That’s right @Alexsc, is a global variable created in my Unit Funcoesdefault. I tried to give a ShowMessage(usuario.ClassName) and I got another Access Violation. I searched my entire project for another possible variable usuario but not found, there is only this.

  • I made a change and the mistake of Access Violation stopped happening. In my Unit Funcoesdefault, where I create my variable usuario:TUsuario, I’m instantiating her in the section Initialization, as follows: usuario := TUsuario.Create. With this no longer gave the error, however, my variable is coming empty. O ShowMessage(usuario.ClassName) is just returning TUsuario. Shouldn’t be FuncoesDefault.TUsuario?

  • I added a few more details to my question, @Alexsc

Show 5 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.