28 de abril de 2009

Ligando .NET e C++ Win32 numa mesma solução

Não é tão comum, mas pode acontecer ter que misturar codificação .NET com codificação Win32. No caso da ABC71, onde temos um legado grande de regras de negócio - para quem não conhece, o 71 do nome é o ano de fundação da empresa - mudar de tecnologia não é um processo simples.
No momento, estamos trabalhando nosso ERP para que ele seja acessível via Web de forma nativa, isto é, sem ter que apelar para gambiarras do tipo "distribuir a aplicação Windows dentro de um VNC ou WTS". O desafio foi fazer isso sem perder todo o conjunto de regras de negócio que já temos validadas e funcionando na versão Windows.

A solução foi incluir um Web Service que recebe solicitações de um applet Java e as distribui para nossas bibliotecas de regras de negócio. Mas, por questão de facilidade no desenvolvimento, o Web Service é um código gerenciado .NET enquanto nossas bibliotecas são em C++ Win32 - portanto, não-gerenciadas. Foi preciso, então, criar uma camada capaz de permitir que esses dois tipos de código se comunicassem.

Pesquisando na Internet, encontrei uma ferramenta que atendeu plenamente esse requisito. Ela se chama SWIG ou Simplified Wrapper and Interface Generator. Apesar de ser uma aplicação simples, sem interface gráfica, é bastante poderosa, permitindo encapsular chamadas de rotinas C++ em diversas linguagens (C#, Java) e em scripts (PERL, Python, Ruby).

No caso da ABC71, montamos uma classe C++ que gerencia chamadas às nossas bibliotecas com as regras legadas e encapsulamos essa classe com SWIG para podermos direcionar a ela as chamadas geradas pelo usuário no applet Java.

Na prática, uma declaração simplificada da classe é assim :


class TWTransactionManager : public BTransaction
{
public:
TWTransactionManager (void);
virtual __fastcall ~TWTransactionManager (void);

virtual TMessageContent getReply (void);
virtual TdomDocument *getDomReply (void);

TWSession *getSession (void);
};

É necessário informar ao SWIG um arquivo contendo as regras para o encapsulamento. Esse arquivo se parece com o reproduzido abaixo :


%module trManagerWEB
%{
#include "WTransactionManager.h"
%}

%include "WTransactionManager.h"

Onde trManagerWeb é o nome da DLL em que a classe está incluída e "WTransactionManager.h" é o header onde está a declaração textual da classe.

Após a execução do SWIG, serão gerados dois conjuntos de arquivos :
1) fontes C++ que preparam a nossa classe para ser chamada externamente. No exemplo, eles têm que ser incluídos no projeto da biblioteca trManagerWeb.
2) fontes C# para serem incluídos no projeto do Web Service, permitindo trabalhar no C# com as classes C++ declaradas na DLL.

Colaborou Arnaldo Marinho.

Nenhum comentário :

Postar um comentário

OBS: Os comentários enviados a este Blog são submetidos a moderação. Por isso, eles serão publicados somente após aprovação.

Observação: somente um membro deste blog pode postar um comentário.