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.

Llama Cualquier Lenguaje desde Harbour

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

ComponenteLenguajeMecanismoCaso de Uso
TPythonPythonAPI C de Python (libpython)Pipelines de ML, ciencia de datos, scripting, automatizacion.
TSwiftSwiftInteroperabilidad C via @_cdeclAPIs nativas macOS/iOS, paquetes Swift.
TGoGoBiblioteca compartida cgo (buildmode=c-shared)Workers concurrentes, microservicios, criptografia.
TNodeNode.jsNode-API (n-api) via runtime embebidoEcosistema npm, frameworks web, E/S asincrona.
TRustRustcdylib con FFI extern "C"Bibliotecas seguras en memoria, codigo critico de rendimiento.
TJavaJavaJNI (Java Native Interface)Bibliotecas Java empresariales, integracion Android.
TDotNetC# / .NETAPI de alojamiento CoreCLREcosistema .NET, paquetes NuGet, interoperabilidad WPF.
TLuaLuaAPI C de Lua (liblua)Scripting ligero, logica de juegos, archivos de configuracion.
TRubyRubyAPI C de Ruby (libruby)Web scraping, procesamiento de texto, DSLs.

Requisitos de Runtime

Cada componente de conectividad requiere su correspondiente toolchain instalado en la maquina host. El componente auto-detecta el binario buscando en rutas comunes; cRuntimePath sobrescribe la deteccion si esta definida.

Toolchain no instalado?

Si falta el toolchain, Start() falla, asigna cLastError con la URL de instalacion y dispara bOnError. El componente no se cuelga — simplemente devuelve .F. / salida vacia.

Componente Herramienta Instalacion (macOS) Rutas auto-detectadas
TPython libpython (embebido) Pre-instalado en macOS, o brew install python /usr/bin/python3, /opt/homebrew/bin/python3
TRust rustc curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ~/.cargo/bin/rustc, /opt/homebrew/bin/rustc, /usr/local/bin/rustc, PATH
TNode node brew install node /opt/homebrew/bin/node, /usr/local/bin/node, /usr/bin/node, PATH
TDotNet SDK dotnet 8+ brew install --cask dotnet-sdk /usr/local/share/dotnet/dotnet, /opt/homebrew/bin/dotnet, ~/.dotnet/dotnet, PATH
TJava javac + java (JDK) brew install openjdk /opt/homebrew/opt/openjdk/bin/javac, /usr/local/opt/openjdk/bin/javac, PATH
TRuby ruby Pre-instalado en macOS, o brew install ruby /opt/homebrew/bin/ruby, /usr/local/bin/ruby, /usr/bin/ruby, PATH
TGo Compilador go brew install go PATH
TSwift swiftc (Xcode CLT) xcode-select --install /usr/bin/swiftc
TLua lua brew install lua /opt/homebrew/bin/lua, /usr/local/bin/lua, PATH

Modelo de Ejecucion

Los lenguajes compilados (Rust, Go, Java, .NET, Swift) siguen un pipeline compilar-luego-ejecutar: fuente → binario en directorio temporal → ejecucion como subproceso. Los interpretados (Node, Ruby, Lua) saltan el paso de build. Python usa libpython embebido para llamadas in-process directas (menor overhead).

ComponenteModoUbicacion del artefacto
TRustCompilar + ejecutar$TMPDIR/hbrust_*/main_*
TDotNetCompilar + ejecutar$TMPDIR/hbdotnet_*/proj_*/bin/Release/net8.0/proj.dll
TJavaCompilar + ejecutar$TMPDIR/hbjava_*/build_*/Main.class
TNodeInterpretar$TMPDIR/hbnode_*.js (eliminado tras ejecutar)
TRubyInterpretar$TMPDIR/hbruby_*.rb (eliminado tras ejecutar)
TPythonEmbebidoIn-process

Eventos Comunes

EventoFirmaCuando se dispara
bOnReady{|oSelf|}Start() termina con exito.
bOnError{|oSelf, cMsg|}Falta toolchain, falla build, falla ejecucion.
bOnOutput{|oSelf, cText|}Stdout producido por Run() / Exec().
bOnBuild{|oSelf, lOk, cBuildOutput|}Tras Build() en runtimes compilados (TRust, TDotNet, TJava, TGo, TSwift).

Metodos API Compartidos

MetodoDevuelveDescripcion
Start()SelfAuto-detecta toolchain. Asigna lRunning, dispara bOnReady o bOnError.
Stop()SelfMarca como detenido, libera binarios temporales (langs compilados).
Exec( cCode )LogicoCompila (si necesita) + ejecuta fuente completa. .T. en exito.
Eval( cExpr )CadenaEnvuelve expresion, ejecuta, devuelve stdout (trim). Inyecta valores de SetVar.
Build( cSource )Logico(Solo compilados) Compila a binario temporal, almacena en cBinPath/cAssemblyPath/cClassDir.
Run( cArgs )Cadena(Solo compilados) Ejecuta el ultimo build con args opcionales. Devuelve stdout.
SetVar( cName, x )LogicoAlmacena valor inyectado como let/var/= antes del proximo Eval/Exec.
GetVar( cName )CualquieraRecupera valor almacenado (cache lado Harbour).

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.

classDiagram class TInteropRuntime { +string cLibPath +string cRuntimePath +logical lInitialized +logical lAutoShutdown +Init() +Eval(cCode) +Call(cFunction, ...args) +SetVar(cName, xValue) +GetVar(cName) +Shutdown() #LoadLibrary(cPath)* #UnloadLibrary()* #MarshalToForeign(xValue)* #MarshalToHarbour(foreignValue)* } TInteropRuntime <|-- TPython TInteropRuntime <|-- TNode TInteropRuntime <|-- TLua TInteropRuntime <|-- TGo TInteropRuntime <|-- TRust TInteropRuntime <|-- TJava TInteropRuntime <|-- TDotNet TInteropRuntime <|-- TSwift TInteropRuntime <|-- TRuby style TInteropRuntime fill:#58a6ff,stroke:#388bfd,color:#0d1117

Propiedades Heredadas

PropiedadTipoValor por defectoDescripcion
cLibPathCadena""Ruta a la biblioteca compartida extranjera (.so, .dll, .dylib).
cRuntimePathCadena""Ruta al ejecutable o VM del runtime (Python, Java, Node, etc.).
lInitializedLogico.F.Verdadero despues de una llamada exitosa a Init() (solo lectura).
lAutoShutdownLogico.T.Llamar automaticamente a Shutdown() al destruir el componente.
nLastErrorCodeNumero0Ultimo codigo de error del runtime extranjero (solo lectura).
cLastErrorCadena""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:

MetodoDescripcion
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:

MetodoParametrosDescripcion
:Init()configuracionInicializar el runtime / cargar la biblioteca.
:Call( cFunction, ...args )nombre funcion + argsLlamar una funcion en el lenguaje extranjero.
:Eval( cCode )cadena de codigo fuenteEjecutar codigo arbitrario en el lenguaje extranjero.
:SetVar( cName, xValue )nombre, valorEstablecer una variable en el entorno del lenguaje extranjero.
:GetVar( cName )nombreObtener 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

graph TB A["Aplicacion Harbour\n(.prg → .hrb)"] --> B["TInteropRuntime\nBase Class"] B --> C1["TPython\nlibpython"] B --> C2["TNode\nNode-API"] B --> C3["TLua\nliblua"] B --> C4["TGo\nc-shared .so"] B --> C5["TRust\ncdylib FFI"] B --> C6["TJava\nJNI"] B --> C7["TDotNet\nCoreCLR"] B --> C8["TSwift\n@_cdecl"] B --> C9["TRuby\nlibruby"] C1 --> D1["Python\nInterpreter"] C2 --> D2["Node.js\nRuntime"] C3 --> D3["Lua\nVM"] C4 --> D4["Go\n.so"] C5 --> D5["Rust\ncdylib"] C6 --> D6["Java\nJVM"] C7 --> D7[".NET\nCLR"] C8 --> D8["Swift\n@_cdecl"] C9 --> D9["Ruby\nVM"] style A fill:#d2a8ff,stroke:#bc8cff,color:#0d1117 style B fill:#58a6ff,stroke:#388bfd,color:#0d1117

Consideraciones de Rendimiento

ComponenteSobrecarga por LlamadaIdeal Para
TPythonBaja (API C directa)Llamadas frecuentes, intercambio de datos.
TLuaMuy baja (VM minima)Bucles ajustados, scripting embebido.
TNodeMedia (marshalling Node-API)Operaciones asincronas, paquetes npm.
TGoBaja (c-shared, FFI directa)Tareas concurrentes de alto rendimiento.
TRustMuy baja (cdylib, costo cero)Computaciones criticas de rendimiento.
TJavaMedia (costo de transicion JNI)Llamadas a bibliotecas empresariales.
TDotNetMedia (alojamiento CoreCLR)Interoperabilidad de bibliotecas .NET.
TSwiftBaja (interoperabilidad C)Funciones nativas macOS/iOS.
TRubyBaja (API C)Ejecucion DSL, procesamiento de texto.
Elegir un Lenguaje

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.

En Esta Página

Lenguajes Soportados Requisitos de Runtime Modelo de Ejecucion Eventos Comunes Metodos API Compartidos Clase Base TInteropRuntime Propiedades Heredadas Metodos Abstractos Patron de API Comun Ejemplo de Integracion con Python Ejemplo de Integracion con Node.js Ejemplo de Integracion con Lua Ejemplo de Integracion con Go Ejemplo de Integracion con Rust Arquitectura Consideraciones de Rendimiento