Connectivity Controls NEW

HarbourBuilder provides 9 language interop controls that let you call code written in Python, Swift, Go, Node.js, Rust, Java, .NET, Lua, and Ruby directly from your Harbour applications. All connectivity components inherit from TInteropRuntime, which provides a unified API for cross-language function calls.

Call Any Language from Harbour

Each connectivity component provides a clean xBase API that wraps the underlying foreign function interface. Drop the component on your form, point it at your script or library, and call functions as if they were native Harbour methods.

Supported Languages

ComponentLanguageMechanismUse Case
TPythonPythonPython C API (libpython)ML pipelines, data science, scripting, automation.
TSwiftSwiftC-interop via @_cdeclmacOS/iOS native APIs, Swift packages.
TGoGocgo shared library (buildmode=c-shared)Concurrent workers, microservices, crypto.
TNodeNode.jsNode-API (n-api) via embedded runtimenpm ecosystem, web frameworks, async I/O.
TRustRustcdylib with extern "C" FFIMemory-safe libraries, performance-critical code.
TJavaJavaJNI (Java Native Interface)Enterprise Java libraries, Android integration.
TDotNetC# / .NETCoreCLR hosting API.NET ecosystem, NuGet packages, WPF interop.
TLuaLuaLua C API (liblua)Lightweight scripting, game logic, config files.
TRubyRubyRuby C API (libruby)Web scraping, text processing, DSLs.

TInteropRuntime Base Class

All 9 connectivity components inherit from TInteropRuntime, an abstract base class that defines the common interface for cross-language communication. This design ensures that switching between languages requires changing only the component class name — the API remains identical.

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

Inherited Properties

PropertyTypeDefaultDescription
cLibPathString""Path to the foreign shared library (.so, .dll, .dylib).
cRuntimePathString""Path to the runtime executable or VM (Python, Java, Node, etc.).
lInitializedLogical.F.True after successful Init() call (read-only).
lAutoShutdownLogical.T.Automatically call Shutdown() on component destroy.
nLastErrorCodeNumeric0Last error code from the foreign runtime (read-only).
cLastErrorString""Last error message description (read-only).

Abstract Methods (implemented by each child)

Each child class must implement these internal methods, which are called by the public API:

MethodDescription
LoadLibrary( cPath )Load the foreign library or initialize the embedded runtime.
UnloadLibrary()Release the library and free resources.
MarshalToForeign( xValue )Convert Harbour values to foreign language types.
MarshalToHarbour( foreignValue )Convert foreign language types back to Harbour.

Common API Pattern

These methods are defined on TInteropRuntime and inherited by all connectivity controls:

MethodParametersDescription
:Init()configurationInitialize the runtime / load the library.
:Call( cFunction, ...args )function name + argsCall a function in the foreign language.
:Eval( cCode )source code stringExecute arbitrary code in the foreign language.
:SetVar( cName, xValue )name, valueSet a variable in the foreign language's environment.
:GetVar( cName )nameGet a variable value from the foreign language.
:Shutdown()Clean up and unload the runtime.

Python Integration Example

The TPython component is the most commonly used connectivity control. It embeds a full Python interpreter in your Harbour application:

#include "hbbuilder.ch"

function Main()

   local oPython, cResult, aData

   // Initialize Python runtime
   oPython := TPython():New()
   oPython:Init()

   // Execute Python code
   oPython:Eval( "import math" )
   cResult := oPython:Call( "math.sqrt", 144 )
   ? "sqrt(144) =", cResult  // 12.0

   // Call a Python function from a script file
   oPython:Eval( ;
      "def greet(name):\n" + ;
      "    return f'Hello, {name} from Python!'\n" + ;
      "def process_list(items):\n" + ;
      "    return [x**2 for x in items]" )

   cResult := oPython:Call( "greet", "Harbour" )
   ? cResult  // "Hello, Harbour from Python!"

   aData := oPython:Call( "process_list", { 1, 2, 3, 4, 5 } )
   // aData = {1, 4, 9, 16, 25}

   oPython:Shutdown()

return nil

Node.js Integration Example

oNode := TNode():New()
oNode:Init()

// Run a JavaScript snippet
cResult := oNode:Eval( ;
   "const os = require('os');" + ;
   "JSON.stringify({ platform: os.platform(), arch: os.arch() })" )

? cResult  // {"platform":"darwin","arch":"arm64"}

oNode:Shutdown()

Lua Integration Example

oLua := TLua():New()
oLua:Init()

// Set a Harbour variable visible in Lua
oLua:SetVar( "app_name", "HarbourBuilder" )

// Run Lua code that accesses it
oLua:Eval( "result = 'Hello from ' .. app_name" )

? oLua:GetVar( "result" )  // "Hello from HarbourBuilder"

oLua:Shutdown()

Go Integration Example

Compile a Go package as a shared library:

// Go source (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()

Rust Integration Example

Compile Rust with cdylib and extern "C":

// Rust source (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()

Architecture

graph TB A["Harbour Application\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

Performance Considerations

ComponentOverhead per CallBest For
TPythonLow (direct C API)Frequent calls, data exchange.
TLuaVery low (minimal VM)Tight loops, embedded scripting.
TNodeMedium (Node-API marshalling)Async operations, npm packages.
TGoLow (C-shared, direct FFI)High-performance concurrent tasks.
TRustVery low (cdylib, zero-cost)Performance-critical computations.
TJavaMedium (JNI transition cost)Enterprise library calls.
TDotNetMedium (CoreCLR hosting).NET library interop.
TSwiftLow (C-interop)macOS/iOS native features.
TRubyLow (C API)DSL execution, text processing.
Choosing a Language

For most scripting needs, TPython or TLua are the simplest to set up. For performance-critical code, use TRust or TGo. For accessing platform-native features on macOS, use TSwift. The right choice depends on your existing codebase and team expertise.

On This Page

Supported Languages TInteropRuntime Base Class Inherited Properties Abstract Methods Common API Pattern Python Integration Example Node.js Integration Example Lua Integration Example Go Integration Example Rust Integration Example Architecture Performance Considerations