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.

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