Integrando UniPaaS e Windows SDK

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

Nestes outros ‘posts’ mostramos como integrar o UniPaaS ao Java e ao .NET/COM.

Agora vamos ver como acessar a API do MS-Windows (Windows SDK): DLLs Win32.

No UniPaaS, podemos chamar rotinas (procedimentos/funções) usando o comando ‘Invoke UDP’ ou as funções CALLDLL(…), CALLDLLS(…) e CALLDLLF(…).

Porque três versões da função CallDll?

Existem três versões porque o UniPaaS suporta até três convenções de chamada: C (CallDll), Standard (CallDllS) e Fast (CallDllF). A convenção define aspectos internos da chamada, como ordenação dos argumentos e limpeza da pilha. É preciso conhecer em qual convenção a DLL foi gerada, para não ativar a rotina de forma errada (o que geralmente causa um GPF). O comando ‘Invoke UDP’ também possui um argumento chamado ‘Convention’ para definir a estrutura da DLL que será chamada. As rotinas da API Windows por padrão são do tipo Standard.

NOTA: Se for criar DLLs em Delphi para uso com o UniPaaS, as funções exportadas devem ser definidas como ‘cdecl’, ‘stdcall’ ou ‘fastcall’ já que o tipo padrão ‘register’ não é reconhecido pelo UniPaaS. Rotinas criadas em C/C++ normalmente são ‘cdecl’.

 

Como optar pelo comando ou pelas funções?

O comando pode sempre ser usado (no lugar das funções), mas o inverso nem sempre é possível. Basicamente trata-se da forma de passagem de parâmetros. O parâmetros em funções UniPaaS (CallDll, CallDllS, CallDllF, etc.) são sempre passados por valor. Já no comando ‘Invoke UDP’, ele poderá ser passado por valor ou por referência. Se a rotina Win32 (DLL) vai atualizar algum dos argumentos recebidos e é necessário recuperar este valor atualizado posteriormente, então é preciso que seja usado o comando ao invés da função.

 

Como chamar a rotina na DLL?

Nas funções, são passados dois argumentos fixos, tipo string, e mais uma série de argumentos que variam conforme a rotina a ser chamada.

O primeiro argumento é <nome_dll>.<nome_rotina>. Não é necessário acrescentar a extensão (.DLL) no nome da biblioteca. Ex: CallDllS( ‘user32.GetSystemMetrics’, … ) está chamando a rotina ‘stdcall’ chamada ‘GetSystemMetrics’ localizada dentro da DLL ‘User32.dll’.

O segundo argumento é um mapa posicional de caracteres que define o tipo de cada argumento da rotina. O último caracter define o tipo do retorno dela. Os tipos aceitos no UniPaaS são:

Ex: CallDllS( ‘user32.GetSystemMetrics’, ‘44’ … ) está chamando a rotina ‘stdcall’ chamada ‘GetSystemMetrics’ localizada dentro da DLL ‘User32.dll’. Ela recebe um argumento do tipo ‘long’ ( ‘4’ ) e retorna também um valor ‘long’ (‘4’).

No comando, é passado um argumento fixo, tipo string, e mais uma série de argumentos que variam cfe. a rotina a ser chamada. Este argumento é o mapa de parâmetros e retorno. Vale a mesma regra das funções (acima), exceto que os parâmetros podem ser passados por referência e atualizados dentro da DLL.

É necessário conhecer a assinatura da rotina (tipos dos argumentos e retorno) para definir corretamente este mapa. Um mapa incorreto geralmente acarreta um GPF durante a execução. Se a rotina não possui argumentos, apenas retorno, informe no mapa apenas o tipo do retorno. Se não possuir retorno, o retorno no mapa deve ser definido como ‘0’. (void)

Dica #1: Ao criar DLLs Delphi, não use o tipo ‘string(ele não é padrão do Windows). Use apenas PAnsiChar ou PWideChar como tipo dos argumentos ou retorno ‘texto’.

Dica #2: Algumas rotinas esperam argumentos que são ponteiros nulos (NULL em C/C++, NIL em Delphi). Como os ponteiros (32 bits) ocupam 4 bytes, no UniPaaS  você pode definir o tipo dele como ‘4’ e passar ‘0’ em seu valor.

Dica #3: Rotinas da API Windows que recebem ou retornam ‘strings’ possuem duas versões: Uma para ANSI e outra para UNICODE. É necessário ser específico no UniPaaS. Se quiser chamar a rotina ‘GetComputerName’ por exemplo, precisar usar o nome correto: GetComputerNameA se os tipos forem ‘alpha’, ou GetComputerNameW se forem ‘Unicode’. Mais detalhes sobre os nomes ou o Windows SDK, estão disponíveis no MSDN.

 

Como é a ligação (bind) com as DLLs?

A ligação no UniPaaS é dinâmica/tardia. O RunTime (UniRTE.exe) e sua aplicação executarão normalmente mesmo que alguma das DLLs utilizadas não estejam disponíveis no momento. Apenas a chamada à rotina é que falhará.

Neste link você poderá baixar uma aplicação exemplo (UniPaaS 1.9g ou JET) onde a API do MS-Windows é utilizada. Num exemplo, a janela principal (MDI) do UniPaaS será centralizada na tela e redefinida para 640 x 480. No outro, a memória física não utilizada atualmente pelo RunTime (UniRTE.exe) será liberada.

Deixe um comentário

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