Tipos Estruturados com o Magic xpa (uniPaaS)

O Magic xpa uniPaaS suporta diferentes tipos de dados para o desenvolvimento de aplicações.

Na versão 1.9i (por exemplo) estes são os tipos disponíveis (atributos de colunas, variáveis ou parâmetros):

  • Alpha: ‘string’ padrão ANSI, onde cada caracter ocupa 1 byte
  • Unicode: ‘string’ padrão UTF-16, onde cada caracter ocupa 2 bytes
  • Numeric: valores numéricos, inteiros ou com casas decimais, com até 38* dígitos
  • Logical: valores lógicos (Verdadeiro ou Falso)
  • Date: Valor numérico representando uma data, entre 01/01/0001 e 31/12/9999
  • Time: Valor numérico representando uma quantidade de segundos, a partir de 0
  • Blob: Um stream de bytes, podendo seu tamanho chegar até 2GB
  • OLE: Referência a um objeto MS.COM OCX
  • ActiveX: Referência a um objeto MS.COM ActiveX
  • .NET: Referência a um objeto do MS.NET FrameWork.
  • Vector: Uma matriz homogênea, de algum dos tipos anteriores (acima)

 (*) requer configuração especial no MAGIC. INI

Em algumas situações, porém, como quando se está interagindo com a API do MS-Windows, a rotina a ser chamada exige um tipo de dado que não está listado aqui: Struct (em C) ou Record (em Pascal).

É um tipo estruturado contendo elementos (campos) de tamanho diferentes, dentro de um bloco.

Por exemplo: a função GlobalMemoryStatus do módulo Kernel32 (API do MS-Windows) requer que seja fornecida uma ‘Struct’ como argumento de chamada, que ela irá preencher (seus elementos) com os dados da memória do sistema. Mais detalhes sobre esta rotina estão no MSDN.

Para estas situações, o uniPaaS permite que utilizemos o tipo ‘Blob’ para criação de ‘Structs’.

A ideia é simples:

Se o ‘Blob’ é uma sequência de bytes:

 

Então iremos alocar uma quantidade ‘n’ de bytes para a estrutura e manipulá-los individualmente, sendo que a ‘Struct’ inicia no byte #1.

O primeiro passo é criar um campo (coluna, variável ou parâmetro) do tipo: Blob, conteúdo: Binary:

 

Em seguida, usaremos as funções do uniPaaS:

BufSet???(): para atualizar as partes (elementos) da estrutura, individualmente.

BufGet???(): para ler os valores destas partes (elementos).

Por exemplo, imagine a seguinte definição de estrutura (em Pascal):

Type

                UniSample = Packed Record

                Field1: Array[0 ..3] of AnsiChar;

                Field2: Integer;

                Field3: SmallInt;

End;

Ela está definindo um tipo estruturado que ocupa, em seu total, 10 bytes. O elemento ‘Field1’ ocupa 4 bytes, ‘Field2’ mais 4 e ‘Field3’ocupa 2. Poderíamos preencher esta estrutura assim (também em Pascal):

                UniSample.Field1 := ‘Bia’;

                UniSample.Field2 := 345;

                UniSample.Field3 := 17;

Para criarmos e preenchermos a mesma estrutura no uniPaaS, seria desta forma:

1)      Definimos um campo Blob/Binary (para fins de exemplo, o identificador interno do campo será ‘IX’).

2)      Gravamos a string ‘Bia’ na posição 1 da estrutura, ocupando 4 bytes:

BufSetAlpha( ‘IX’VAR, 1, ‘Bia’, 3, 4, ‘FALSE’LOG ).

3)      Gravamos o número 345 na posição 5 da estrutura, ocupando 4 bytes:

BufSetNum( ‘IX’VAR, 5, 345, 4, 4, ‘FALSE’LOG ).

4)      Gravamos o número 17 na posição 9 da estrutura, ocupando 2 bytes:

BufSetNum( ‘IX’VAR, 9, 17, 4, 2, ‘FALSE’LOG ).

 

O resultado dentro do Blob é este:


 

NOTA #1: Cada quadro acima representa um byte, e o conteúdo é ilustrativo.

NOTA #2: A alocação de memória é totalmente automática, com base nos argumentos ‘position’ e ‘length’ utilizados.

NOTA #3: ‘Bia’ tem 3 caracteres, mas ocupa 4 bytes. Isso porque o tipo interno é ZString.

 

Com o argumento ‘position’ das funções, dizemos onde iniciar o acesso dentro da estrutura.

Com o argumento ‘length’ informamos quantos bytes o dado deverá ocupar.

O argumento ‘storage’ informa como o dado deve ser internamente armazenado.

O argumento ‘variable’ indica qual o ‘Blob’ a ser atualizado.

O argumento ‘as pointer’ indica se só o endereço do dado (TRUE) está no ‘Blob’, ou o próprio conteúdo (FALSE) é que está naquela posição.

E no caso das funções BufSet???(), ainda temos o argumento ‘value’ que é o dado a ser armazenado.

Estes tipos estruturados no uniPaaS serão, em sua grande maioria das vezes, utilizados na integração com DLLs Win32 (CALLDLL, CALLDLLS, CALLDLLF e InvokeUDP). Para informar ao uniPaaS que o argumento passado é uma ‘Struct’, utiliza-se o descritor ‘T’ no mapa de argumentos. Veja aqui mais detalhes sobre o acesso a DLLs através do uniPaaS.

Neste endereço você pode baixar um projeto exemplo, onde uma ‘Struct’ é criada e preenchida, passada como argumento para a API do MS.Windows, e em seguida seus valores (atualizados) são lidos e apresentados na tela.

 

Manoel Frederico - Gerente de Produto e Magic Evangelista

Manoel Frederico Silva
Product Manager & MAGIC Evangelist / Magic Software Brasil 

 

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *