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.
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
| Component | Language | Mechanism | Use Case |
|---|---|---|---|
| TPython | Python | Python C API (libpython) | ML pipelines, data science, scripting, automation. |
| TSwift | Swift | C-interop via @_cdecl | macOS/iOS native APIs, Swift packages. |
| TGo | Go | cgo shared library (buildmode=c-shared) | Concurrent workers, microservices, crypto. |
| TNode | Node.js | Node-API (n-api) via embedded runtime | npm ecosystem, web frameworks, async I/O. |
| TRust | Rust | cdylib with extern "C" FFI | Memory-safe libraries, performance-critical code. |
| TJava | Java | JNI (Java Native Interface) | Enterprise Java libraries, Android integration. |
| TDotNet | C# / .NET | CoreCLR hosting API | .NET ecosystem, NuGet packages, WPF interop. |
| TLua | Lua | Lua C API (liblua) | Lightweight scripting, game logic, config files. |
| TRuby | Ruby | Ruby 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.
Inherited Properties
| Property | Type | Default | Description |
|---|---|---|---|
cLibPath | String | "" | Path to the foreign shared library (.so, .dll, .dylib). |
cRuntimePath | String | "" | Path to the runtime executable or VM (Python, Java, Node, etc.). |
lInitialized | Logical | .F. | True after successful Init() call (read-only). |
lAutoShutdown | Logical | .T. | Automatically call Shutdown() on component destroy. |
nLastErrorCode | Numeric | 0 | Last error code from the foreign runtime (read-only). |
cLastError | String | "" | 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:
| Method | Description |
|---|---|
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:
| Method | Parameters | Description |
|---|---|---|
:Init() | configuration | Initialize the runtime / load the library. |
:Call( cFunction, ...args ) | function name + args | Call a function in the foreign language. |
:Eval( cCode ) | source code string | Execute arbitrary code in the foreign language. |
:SetVar( cName, xValue ) | name, value | Set a variable in the foreign language's environment. |
:GetVar( cName ) | name | Get 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
Performance Considerations
| Component | Overhead per Call | Best For |
|---|---|---|
| TPython | Low (direct C API) | Frequent calls, data exchange. |
| TLua | Very low (minimal VM) | Tight loops, embedded scripting. |
| TNode | Medium (Node-API marshalling) | Async operations, npm packages. |
| TGo | Low (C-shared, direct FFI) | High-performance concurrent tasks. |
| TRust | Very low (cdylib, zero-cost) | Performance-critical computations. |
| TJava | Medium (JNI transition cost) | Enterprise library calls. |
| TDotNet | Medium (CoreCLR hosting) | .NET library interop. |
| TSwift | Low (C-interop) | macOS/iOS native features. |
| TRuby | Low (C API) | DSL execution, text processing. |
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.