FFI — Foreign Function Interface

Archivo: src/ffi.rs (289 líneas)

¿Por qué existe?

Permite que los programas Forja llamen funciones de librerías nativas (.dll en Windows, .so/.dylib en Unix) cargadas con importar externa. Provee el registro global de librerías y las funciones nativas _ffi_obtener_funcion, _ffi_llamar_entero y _ffi_llamar_texto que la VM usa para resolver y ejecutar punteros a función externos.

Arquitectura / Estructuras clave

ComponenteDescripción
LibHandleWrapper de *mut c_void que implementa Send + Sync (el puntero raw no es Send por defecto)
FFI_REGISTRYOnceLock<Mutex<HashMap<String, LibHandle>>>: registro global ruta → handle
registry()Acceso lazy al registro global (inicialización única)
Declaraciones OSextern "system": LoadLibraryW, GetProcAddress, FreeLibrary, GetLastError (Windows) · extern "C": dlopen, dlsym, dlclose, dlerror + constantes RTLD_LAZY/RTLD_LOCAL (Unix)

API pública

FunciónDescripción
esta_cargada(ruta) -> boolVerifica si la librería ya está en el registro
cargar_libreria(ruta) -> Result<i64, String>Carga vía LoadLibraryW (Windows) o dlopen (Unix); si ya está cargada devuelve el handle existente. El handle se convierte a i64 como id opaco
obtener_funcion(ruta, nombre) -> Result<i64, String>Resuelve un puntero a función con GetProcAddress (Windows) o dlsym (Unix); error si la librería no está cargada
liberar_libreria(ruta) -> Result<(), String>Descarga la librería con FreeLibrary / dlclose
ruta_libreria_sistema(nombre)Resuelve nombres de librería del sistema (p. ej. "msvcrt.dll"; en Unix agrega prefijo lib/sufijo .so)

Funciones nativas de la VM

NativaFirma ForjaDescripción
native_ffi_obtener_funcion_ffi_obtener_funcion(ruta, nombre) -> EnteroResuelve el puntero a función y lo devuelve como entero; retorna -1 si falla
native_ffi_llamar_entero_ffi_llamar_entero(fn_ptr, args: arreglo<Entero>) -> EnteroHace transmute del puntero a extern "C" fn y lo invoca con 0 a 5 argumentos i64
native_ffi_llamar_texto_ffi_llamar_texto(fn_ptr, args: arreglo<Texto>) -> TextoInvoca una función que retorna char* (convierte argumentos a CString, hasta 2 args) y convierte el resultado a Texto de la VM
Cuidado: el puntero viaja como i64 y se convierte a usize + *const () antes del transmute para que sea válido también en arquitecturas de 32 bits (wasm32). _ffi_llamar_entero soporta hasta 5 argumentos y _ffi_llamar_texto hasta 2; más allá, se retorna error de tipo.
Ciclo de vida: el programa debe cargar la librería primero con importar externa (que llama cargar_libreria), resolver cada función con _ffi_obtener_funcion, y al finalizar liberar_libreria para descargarla del registro global.