
_Créditos das imagens: ChatGPT
🚀 **DynCall no Protheus: Uma Nova Era na Integração com C/C++**
Do meu ponto de vista, um dos recursos mais interessantes na nova versão do Protheus "Onça Preta" é a possibilidade de uso do **DynCall**.
A linguagem AdvPL/TLPP, utilizada no Protheus, pode ser considerada um "superconjunto" de Clipper com FiveWin, mas com características e funcionalidades específicas voltadas para o ecossistema TOTVS. Um dos recursos marcantes do Clipper e de linguagens padrão xBase, como Harbour, é a possibilidade de incorporar código C/C++ diretamente no código-fonte. Até então, o Protheus não suportava isso nativamente. No entanto, com a introdução do **DynCall**, é possível simular essa integração ao carregar e executar funções de bibliotecas dinâmicas (DLLs) escritas em C ou C++. A seguir, comparamos os recursos das linguagens xBase padrão (exemplificadas pelo Harbour) com a implementação no Protheus via DynCall e apresentamos exemplos dos novos recursos oferecidos por essa tecnologia.
---
### **Recursos em Linguagens Padrão xBase (Harbour)**
Nas linguagens xBase padrão, como o Harbour, é possível incorporar código C/C++ diretamente no mesmo arquivo de código usando diretivas como `#pragma BEGINDUMP` e `#pragma ENDDUMP`. Isso permite que funções escritas em C/C++ sejam chamadas de forma natural no código xBase, como se fossem funções nativas. Veja um exemplo:
```c
#pragma BEGINDUMP
#include "hbapi.h"
HB_FUNC(STROCCURS)
{
const char *s1 = hb_parc(1);
char *s2 = hb_parc(2);
HB_SIZE len = hb_parclen(2);
HB_SIZE count = 0;
for (HB_SIZE i = 0; i < len; i++) {
if (s1[0] == s2[i]) count++;
}
hb_retns(count);
}
#pragma ENDDUMP
```
Nesse caso:
- A função `STROCCURS` é escrita em C e integrada diretamente no Harbour.
- Após a compilação, pode ser chamada no código xBase como qualquer outra função: `nCount := STROCCURS("a", "banana")`.
Esse modelo oferece uma integração perfeita, mas exige que o código C/C++ seja compilado junto com o código xBase, limitando a flexibilidade em cenários onde bibliotecas externas já existem.
---
### **Implementação no Protheus com DynCall**
No Protheus, a incorporação direta de código C/C++ não é suportada. Em vez disso, o **DynCall** permite carregar bibliotecas dinâmicas (DLLs) em tempo de execução e chamar suas funções ou métodos. Isso simula a integração com código de baixo nível, mas com uma abordagem diferente. Vamos analisar como isso funciona.
#### **Exemplo Básico com DynCall**
Considere uma DLL em C que exporta uma função simples de soma:
```c
#define EXPORT __declspec(dllexport)
EXPORT int add(int a, int b)
{
return a + b;
}
```
No Protheus, essa função pode ser chamada usando DynCall assim:
```advpl
#include "tlpp-core.th"
Function U_SimpleDynCall()
Local oDll := tRunDll():New("dllc.dll")
Local nValue as Numeric
oDll:CallFunction("add", "III", nValue, 4, 8)
Conout("Resultado: " + cValToChar(nValue)) // Resultado: 12
oDll:Free()
Return
```
### **Comparação entre Harbour e Protheus com DynCall**
| **Aspecto** | **Harbour (xBase Padrão)** | **Protheus com DynCall** |
|------------------------|----------------------------------------------------|--------------------------------------------------|
| **Integração** | Código C/C++ é incorporado diretamente no fonte. | Requer uma DLL externa carregada dinamicamente. |
| **Flexibilidade** | Menos flexível; exige recompilação do projeto. | Mais flexível; permite usar DLLs pré-existentes.|
| **Naturalidade** | Chamada direta como função nativa. | Usa API DynCall, com assinaturas explícitas. |
| **Portabilidade** | Depende da compilação para cada plataforma. | Suporta Windows e Linux com a mesma lógica. |
| **Resiliência** | Sem isolamento nativo; crashes afetam o programa. | Sandbox isola a DLL, com timeouts configuráveis.|
O DynCall no Protheus permite, além de chamadas simples a funções, a invocação de métodos de classes C++, acesso a variáveis globais e manipulação de ponteiros.
---
### **DynCall no Harbour**
O Harbour também possui suporte para DynCall via funções como `hb_libLoad()` e `hb_libCall()`. Um exemplo pode ser encontrado neste repositório: [Harbour DLL Example](https://raw.githubusercontent.com/naldodj/naldodj-harbour-core/81be99f647f8e752c05ba782e3ca4d5e9333c2c9/contrib/hbfoxpro/dll.prg).
---
### **Conclusão**
Embora o Protheus não suporte a incorporação direta de código C/C++ como o Harbour, o **DynCall** oferece uma alternativa poderosa para integrar bibliotecas dinâmicas. Ele permite chamar funções e métodos, acessar variáveis globais, gerenciar ponteiros e configurar timeouts, tudo com um modelo de sandbox que garante resiliência. Comparado ao Harbour, o DynCall troca a simplicidade da integração direta por maior flexibilidade e portabilidade, sendo ideal para cenários onde é necessário usar bibliotecas externas ou estender o Protheus com código de baixo nível de forma segura e robusta.
⚠️ **Observação:** Infelizmente, o DynCall no Protheus está disponível apenas para uso interno da TOTVS.
---
### ***Hashtags***
#AdvPL, #TLPP, #Protheus, #TOTVS, #DynCall, #Cplusplus, #Harbour, #xBase, #ERP, #Desenvolvimento
Comentários
Postar um comentário