Controles de Conectividad NUEVO
HarbourBuilder proporciona 9 controles de interoperabilidad de lenguajes que te permiten llamar codigo escrito en Python, Swift, Go, Node.js, Rust, Java, .NET, Lua y Ruby directamente desde tus aplicaciones Harbour. Los 9 controles heredan de la clase base TInteropRuntime, que proporciona una API unificada para llamadas entre lenguajes.
Cada componente de conectividad proporciona una API xBase limpia que envuelve la interfaz de funcion extranjera subyacente. Coloca el componente en tu formulario, apuntalo a tu script o biblioteca, y llama funciones como si fueran metodos nativos de Harbour.
Lenguajes Soportados
| Componente | Lenguaje | Mecanismo | Caso de Uso |
|---|---|---|---|
| TPython | Python | API C de Python (libpython) | Pipelines de ML, ciencia de datos, scripting, automatizacion. |
| TSwift | Swift | Interoperabilidad C via @_cdecl | APIs nativas macOS/iOS, paquetes Swift. |
| TGo | Go | Biblioteca compartida cgo (buildmode=c-shared) | Workers concurrentes, microservicios, criptografia. |
| TNode | Node.js | Node-API (n-api) via runtime embebido | Ecosistema npm, frameworks web, E/S asincrona. |
| TRust | Rust | cdylib con FFI extern "C" | Bibliotecas seguras en memoria, codigo critico de rendimiento. |
| TJava | Java | JNI (Java Native Interface) | Bibliotecas Java empresariales, integracion Android. |
| TDotNet | C# / .NET | API de alojamiento CoreCLR | Ecosistema .NET, paquetes NuGet, interoperabilidad WPF. |
| TLua | Lua | API C de Lua (liblua) | Scripting ligero, logica de juegos, archivos de configuracion. |
| TRuby | Ruby | API C de Ruby (libruby) | Web scraping, procesamiento de texto, DSLs. |
Clase Base TInteropRuntime
Los 9 controles de conectividad heredan de TInteropRuntime, una clase base abstracta que define la interfaz comun para la comunicacion entre lenguajes. Este diseno asegura que cambiar entre lenguajes solo requiere modificar el nombre de la clase del componente — la API permanece identica.
Propiedades Heredadas
| Propiedad | Tipo | Valor por defecto | Descripcion |
|---|---|---|---|
cLibPath | Cadena | "" | Ruta a la biblioteca compartida extranjera (.so, .dll, .dylib). |
cRuntimePath | Cadena | "" | Ruta al ejecutable o VM del runtime (Python, Java, Node, etc.). |
lInitialized | Logico | .F. | Verdadero despues de una llamada exitosa a Init() (solo lectura). |
lAutoShutdown | Logico | .T. | Llamar automaticamente a Shutdown() al destruir el componente. |
nLastErrorCode | Numero | 0 | Ultimo codigo de error del runtime extranjero (solo lectura). |
cLastError | Cadena | "" | Descripcion del ultimo mensaje de error (solo lectura). |
Metodos Abstractos
Cada clase hija debe implementar estos metodos internos, que son llamados por la API publica:
| Metodo | Descripcion |
|---|---|
LoadLibrary( cPath ) | Cargar la biblioteca o inicializar el runtime embebido. |
UnloadLibrary() | Liberar la biblioteca y los recursos. |
MarshalToForeign( xValue ) | Convertir valores Harbour a tipos del lenguaje extranjero. |
MarshalToHarbour( foreignValue ) | Convertir tipos del lenguaje extranjero de vuelta a Harbour. |
Patron de API Comun
Estos metodos estan definidos en TInteropRuntime y son heredados por todos los controles de conectividad:
| Metodo | Parametros | Descripcion |
|---|---|---|
:Init() | configuracion | Inicializar el runtime / cargar la biblioteca. |
:Call( cFunction, ...args ) | nombre funcion + args | Llamar una funcion en el lenguaje extranjero. |
:Eval( cCode ) | cadena de codigo fuente | Ejecutar codigo arbitrario en el lenguaje extranjero. |
:SetVar( cName, xValue ) | nombre, valor | Establecer una variable en el entorno del lenguaje extranjero. |
:GetVar( cName ) | nombre | Obtener el valor de una variable del lenguaje extranjero. |
:Shutdown() | — | Limpiar y descargar el runtime. |
Ejemplo de Integracion con Python
El componente TPython es el control de conectividad mas comunmente usado. Incrusta un interprete Python completo en tu aplicacion Harbour:
#include "hbbuilder.ch" function Main() local oPython, cResultado, aDatos // Inicializar runtime Python oPython := TPython():New() oPython:Init() // Ejecutar codigo Python oPython:Eval( "import math" ) cResultado := oPython:Call( "math.sqrt", 144 ) ? "sqrt(144) =", cResultado // 12.0 // Llamar una funcion Python desde un archivo de script oPython:Eval( ; "def greet(name):\n" + ; " return f'¡Hola, {name} desde Python!'\n" + ; "def process_list(items):\n" + ; " return [x**2 for x in items]" ) cResultado := oPython:Call( "greet", "Harbour" ) ? cResultado // "¡Hola, Harbour desde Python!" aDatos := oPython:Call( "process_list", { 1, 2, 3, 4, 5 } ) // aDatos = {1, 4, 9, 16, 25} oPython:Shutdown() return nil
Ejemplo de Integracion con Node.js
oNode := TNode():New() oNode:Init() // Ejecutar un fragmento JavaScript cResultado := oNode:Eval( ; "const os = require('os');" + ; "JSON.stringify({ platform: os.platform(), arch: os.arch() })" ) ? cResultado // {"platform":"darwin","arch":"arm64"} oNode:Shutdown()
Ejemplo de Integracion con Lua
oLua := TLua():New() oLua:Init() // Establecer una variable Harbour visible en Lua oLua:SetVar( "app_name", "HarbourBuilder" ) // Ejecutar codigo Lua que accede a ella oLua:Eval( "result = 'Hola desde ' .. app_name" ) ? oLua:GetVar( "result" ) // "Hola desde HarbourBuilder" oLua:Shutdown()
Ejemplo de Integracion con Go
Compila un paquete Go como biblioteca compartida:
// Fuente Go (golib.go) // export Double func Double(n C.int) C.int { return n * 2 } // Build: go build -buildmode=c-shared -o golib.so golib.go
oGo := TGo():New() oGo:cLibPath := "./golib.so" oGo:Init() ? oGo:Call( "Double", 21 ) // 42 oGo:Shutdown()
Ejemplo de Integracion con Rust
Compila Rust con cdylib y extern "C":
// Fuente Rust (src/lib.rs) #[no_mangle] pub extern "C" fn hash_string(s: *const c_char) -> *mut c_char { let input = unsafe { CStr::from_ptr(s).to_str().unwrap() }; let hash = format!("{:x}", md5::compute(input)); CString::new(hash).unwrap().into_raw() } // Build: cargo build --release
oRust := TRust():New() oRust:cLibPath := "./target/release/libmylib.so" oRust:Init() ? oRust:Call( "hash_string", "hello" ) // "5d41402abc4b2a76b9719d911017c592" oRust:Shutdown()
Arquitectura
Consideraciones de Rendimiento
| Componente | Sobrecarga por Llamada | Ideal Para |
|---|---|---|
| TPython | Baja (API C directa) | Llamadas frecuentes, intercambio de datos. |
| TLua | Muy baja (VM minima) | Bucles ajustados, scripting embebido. |
| TNode | Media (marshalling Node-API) | Operaciones asincronas, paquetes npm. |
| TGo | Baja (c-shared, FFI directa) | Tareas concurrentes de alto rendimiento. |
| TRust | Muy baja (cdylib, costo cero) | Computaciones criticas de rendimiento. |
| TJava | Media (costo de transicion JNI) | Llamadas a bibliotecas empresariales. |
| TDotNet | Media (alojamiento CoreCLR) | Interoperabilidad de bibliotecas .NET. |
| TSwift | Baja (interoperabilidad C) | Funciones nativas macOS/iOS. |
| TRuby | Baja (API C) | Ejecucion DSL, procesamiento de texto. |
Para la mayoria de las necesidades de scripting, TPython o TLua son los mas simples de configurar. Para codigo critico de rendimiento, usa TRust o TGo. Para acceder a funciones nativas de la plataforma en macOS, usa TSwift. La eleccion correcta depende de tu base de codigo existente y la experiencia de tu equipo.