{"id":23213771,"url":"https://github.com/metaffi/metaffi-core","last_synced_at":"2026-02-19T00:34:13.106Z","repository":{"id":165283341,"uuid":"260844625","full_name":"MetaFFI/metaffi-core","owner":"MetaFFI","description":"Simple Program Languages Interoperability","archived":false,"fork":false,"pushed_at":"2026-02-06T16:54:13.000Z","size":665,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-07T00:48:06.596Z","etag":null,"topics":["go","golang","interoperability","java","python"],"latest_commit_sha":null,"homepage":"https://metaffi.github.io/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MetaFFI.png","metadata":{"files":{"readme":null,"changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-05-03T06:46:14.000Z","updated_at":"2026-02-06T16:54:16.000Z","dependencies_parsed_at":"2024-04-04T19:25:18.728Z","dependency_job_id":"c8f13277-56eb-4c92-bbbc-00b4eb56ecde","html_url":"https://github.com/MetaFFI/metaffi-core","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/MetaFFI/metaffi-core","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MetaFFI%2Fmetaffi-core","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MetaFFI%2Fmetaffi-core/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MetaFFI%2Fmetaffi-core/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MetaFFI%2Fmetaffi-core/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MetaFFI","download_url":"https://codeload.github.com/MetaFFI/metaffi-core/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MetaFFI%2Fmetaffi-core/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29599375,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T22:25:43.180Z","status":"ssl_error","status_checked_at":"2026-02-18T22:25:42.766Z","response_time":162,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","interoperability","java","python"],"created_at":"2024-12-18T19:19:13.689Z","updated_at":"2026-02-19T00:34:13.098Z","avatar_url":"https://github.com/MetaFFI.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MetaFFI Framework\n\n**Latest Version: 0.0.3**\n\nMetaFFI framework is a simple and easy way to call functions in different programming languages.\n\nJump to:\n* [Usage section](#usage)\n* [Download section](#download)\n \n\n## Do you need MetaFFI?\n* Are you tired of searching for that library only in your project's language?\n\n* The library you're looking for is available only in a different language?\n\n* Don't want to settle for a library port and use the real thing???\n\n* Are you really going re-write this code just because it's in a different language than your project?!\n\n* Tired of *language interop hell* to connect different languages in your project?\n\n**WORRY NO MORE - *MetaFFI* is exactly what you need!**\n\n\n\u003cBR\u003e\n\nMetaFFI Framework provides an easy, simple and straightforward way to call functions from one programming language to another. The framework hides from the user and encapsulates all the hassle of performing FFI calls ([Foreign Function Interface](https://en.wikipedia.org/wiki/Foreign_function_interface) - calling a function in another language). MetaFFI by itself is **not** an FFI solution, but it inter-connects seamlessly different FFIs to provide a simple, clean, unified mechanism. \n\n#### World without MetaFFI\nFor example, I want to call from *Go* to *Python3* and vice-versa.\\\nLet's see how it looks **without MetaFFI** (there might be other techniques, but none is easy):\n\n__Go \u0026rarr; Python3__:\n1. Write a C function exposed to [CGo](https://golang.org/cmd/cgo/) that receives the Python3 function parameters in C data types. The function needs to implement the following using [Python3 C-API](https://docs.python.org/3/c-api/index.html):\n    1. Load Python3 runtime\n    2. Load Python3 module containing the function of your choice\n    3. Convert the parameters in C data types to \"Pythonic\" data types\n    4. Call the Python3 function\n    5. Get the return values (can be multiple of them in Python3) from Python runtime\n    6. Convert the multiple return values into C data types\n    7. Return the multiple return values from the C-function (using a C-struct)\n    8. **Handle error \u0026 exceptions** in both Python and C and return them instead of the \"return values\" in case of an error (using the C-struct?)\n    9. **Handle multi-threading** in case multiple goroutines are calling the Python function at the same time\n    10. Avoid the many pitfalls on the way...\n   \n2. Write Go function that receives the Pythonic function parameters in Go data types. The function needs to implement the following:\n    1. Convert Go data types to C data types. Allocate memory and all other things required for C parameters\n    2. call C function implemented in step 1\n    3. Receive the returned C-struct\n    4. Convert Python multiple return values from C to Go\n    5. Free all allocated memory\n    6. **Handle errors** returned from C and convert them to Go to return them to the caller\n    7. **Handle multi-threading** in case multiple goroutines are calling the Python function at the same time\n    8. Avoid the many pitfalls on the way...\n   \nIt is essential to point out that different Pythonic functions require other C functions.\n\n__Python3 \u0026rarr; Go__: \\\nThe other way around is a completely different mechanism:\n1. In Go:\n    1. Export the function you want to call from Python using CGo (//export comment)\n    2. Build Go C-Shared dynamic library (.dll, .so or .dylib) exporting the function in C. In case of multiple return values, CGo generates a C struct to holding them.\n2. In Python3:\n    1. Using (CTypes)[https://docs.python.org/3.8/library/ctypes.html] load Go's dynamic library\n    2. Convert Python data types to CTypes data types\n    3. Load Go dynamic library\n    4. Load Go exported function (exported in C)\n    5. Call exported function and receive CGo generated struct holding multiple return values\n    6. Extract return values from C-struct and convert them to Pythonic data types\n    7. Free any allocated memory\n    8. **Handle errors** returning from Go\n    9. Avoid the many pitfalls on the way...\n\nThat's it! Easy as rocket science in the stone age! :tired_face:\n\n#### World With MetaFFI\nI want to call from *Go* to function `f(params)` *Python3* and vice-versa, but this time with MetaFFI!\n\n__Go \u0026rarr; Python3__:\n1. Define your function in Protobuf using a [.proto](https://developers.google.com/protocol-buffers/docs/proto3) file\n2. Compile the `.proto` file using MetaFFI is stating you want to call from Go to Python3: `metaffi -c --idl myfuncs.proto -t --from go`\n\nThat's it!\n\nMetaFFI generated a `myfuncsMetaFFIHost.go` file with an `f(params)` stub to call natively from Go, with Go data types!\n\n__Python3 \u0026rarr; Go__: \\\n1. Define your function in Protobuf using a [.proto](https://developers.google.com/protocol-buffers/docs/proto3#services) file\n2. Compile the `.proto` file using MetaFFI is stating you want to call from Go to Python3: `metaffi -c --idl myfuncs.proto -t --from python3`\n\nYou're Done!\n\nMetaFFI generated a `myfuncsMetaFFIHost.py` file with an `f(params)` stub to call natively from Python3, with Pythonic data types!\n\n\u003cBR /\u003e\n\n**Now, That's easy!**\n\nDetailed examples can be found in the [Tutorials](#tutorials) section\n\n\n## Terminology for the rest of the readme\n* *Foreign function* - The function you want to call in a different language\n* *Host language* - The language you're calling from\n* *Guest language* - The language you're calling to\n* *IDL ([Interface Definition Language](https://en.wikipedia.org/wiki/IDL_(programming_language)))* - File defining the functions you're calling to. Currently, the official supported languages are using `.proto`, Google's Protobuf IDL.\n\n## Usage\n\n### Calling Foreign Function\n\n1. Write IDL (`.proto` for current official languages) defining your function(s):\n\nGoUtils.proto:\n```\nsyntax = \"proto3\";\n\n// metaffi_target_lang: \"go\"\noption go_package = \"main\";\n\n//--------------------------------------------------------------------\nservice GoUtils { // metaffi_module: \"github.com/Masterminds/goutils\"\n   rpc Initials (initials_params) returns (initials_return);\n}\n//--------------------------------------------------------------------\nmessage initials_params {\n   string input = 1;\n}\nmessage initials_return {\n   string result = 1;\n}\n//--------------------------------------------------------------------\n```\nThe `metaffi_target_lang` tag states the foreign language MetaFFI should use to call this function.\n\nThe `metaffi_module` tag tells MetaFFI the name of the module. In case it doesn't exist, it uses \"service\" name.\n\n2. Run MetaFFI CLI tool to compile `PythonFuncs.proto`: \\\n`metaffi -c --idl GoUtils.proto -f python3 -t`\n\n* `-c` (or `--compile`) - Tells MetaFFI to compile\n* `--idl` - State the IDL to compile\n* `-f` (or `--from`) - State the language(s) you're calling from\n* `-t` (or `--to`) - Tells MetaFFI to generate code that links MetaFFI runtime to the foreign function\n\n3. Use the code!\n```\nfrom GoUtilsMetaFFIHost import * # This module contains the Python stub\n\n# call foreign functions via MetaFFI\nres = Initials('James Tiberius Kirk')\nprint(res) # prints 'JTK'\n```\n\n### Managing Installed Languages (i.e. Plugins)\nMetaFFI comes with 2 languages support:\n* Python3\n* Go\n\nPlugin management is available using MetaFFI CLI tool with the `-p` (or `--plugin`) switch.\n\n* To list installed plugins:\n`metaffi -p --list`\n\nTo install a plugin:\n`metaffi -p -i [plugin URL or local path]` \\\nFor example, `metaffi -p -i https://github.com/GreenFuze/MetaFFI/releases/download/v0.0.3/metaffi-ubuntu-python3.tar.gz`\n\nTo remove a plugin run:\n`metaffi -p -r [plugin]` \\\n For example, `metaffi -p -r python3`\n\n## Installation\n\n### Prerequisites\n\nCurrent official languages use Protobuf Compiler for data serialization (detailed in [Data-Type Serialization \u0026 Protobuf section](#data-otype-serialization-\u0026-protobuf)). Therefore Google Protobuf need to be installed.\n\n**Notice:** Deployed machines (not for developers) do not need Protobuf compiler. It is just for development needs. `-redist` (TBD!) option in MetaFFI CLI tool will provide you with all the binaries needed for deployment.\n\n* Go support requires `protoc-gen-go`, Protobuf's Go support which can be found [here](https://github.com/golang/protobuf). \n\n* Python3 support requires `protobuf` python package\n\n### Download\n#### Version 0.0.3-alpha\n* [Windows - metaffi-windows-v0.0.3.zip](https://github.com/GreenFuze/MetaFFI/releases/download/v0.0.3/metaffi-windows-v0.0.3.zip)\n* [Ubuntu - metaffi-ubuntu-v0.0.3.tar.gz](https://github.com/GreenFuze/MetaFFI/releases/download/v0.0.3/metaffi-ubuntu-v0.0.3.tar.gz)\n* [MacOS - metaffi-macos-v0.0.3.tar.gz\n](https://github.com/GreenFuze/MetaFFI/releases/download/v0.0.3/metaffi-macos-v0.0.3.tar.gz)\n\n### Install\nDownload MetaFFI for your operating system and run the `install` script. Notice you will need administrative rights to install.\n* Linux/Mac - `sudo ./install.sh`\n* Windows - In Command Prompt with Administrative rights run `install.bat`\n\n## Official Supported Languages\nMetaFFI comes with 2 supported languages:\n* Python3\n* Go\n\n### Tested Environments\n| Operating System | Version |\n| :---: | :---: |\n| Windows | 10 Pro |\n| Ubuntu | 20.04 |\n| MacOS | Catalina 10.15 |\n\n| Language | Version |\n| :---: | :---: |\n| Go | 1.12.17 |\n| Python3 | 3.8.2 |\n\n## Build From Source\nDetailed in [/build-scripts/README.md](build-scripts/README.MD)\n\n## MetaFFI Internals (in a nutshell)\nMetaFFI design is entirely modular, built out of plugins loaded in runtime to support different languages, runtime and serializations.\n\nEach language support is an MetaFFI plugin built out of 2 parts:\n1. XLLR - Used during runtime\n2. Compiler - Used during compile time\n\nMetaFFI uses in-direct FFI to link the supported languages together. No supported language knows how to call another directly. Instead, MetaFFI uses FFI from C and FFI to C to form a link between two supported languages. This approach allows an MetaFFI plugin implementer to implement only C-FFI to gain function calls to **all** the MetaFFI supported languages.\n\n### Cross-Language Linker Runtime (XLLR)\nXLLR links the host language and the foreign language during runtime. It exposes C-API to call an arbitrary function in the requested language.\n\nOnce XLLR called, it loads an XLLR-plugin which handles the requested guest language and passes the call to it. The plugin handles the actual call.\n\nIt is the XLLR plugin that implements foreign language runtime management.\\\nFor example, while the official *Python3* plugin uses the stock Python3 which uses CPython, another implementer can make a *Pypy3* plugin that uses Pypy engine instead of CPython. Users will be able to install the new plugin using the `metaffi -p -i [URL]` command. \n\n### Compiler\nThe MetaFFI compiler has 3 roles:\n1. Generate stub for the foreign function in the host language\n2. Serialize/Deserialize parameters (official plugins use Google Protobuf)\n3. Use C-FFI library to call to/from XLLR in host/guest languages\n\nIt is the compiler plugin that chooses the C-FFI mechanism used or the otype of parameter serialization.\n\nFor example, the official *Python3* plugin uses CTypes for C-FFI and Protobuf serialization with `.proto` IDL. Another implementer can make *FasterPython3* plugin that uses \"cffi\" to C-FFI and FlatBuffers for serialization with its IDL. \n \n\n### MetaFFI In-Direct FFI Star-Graph vs Common Direct FFI Clique-Graph\nFFI libraries provide direct linking from language L1 to L2, this forces developers to learn, maintain and understand multiple libraries. Just a few well-known examples are:\n* Python CTypes: FFI Python → C\n* JNI: JAVA → C\n* CGo: Go → C\n* Boost.Python: C++ → Python\n* P/Invoke: CRL → C\n\nFrom the above, we understand that when Go users wish to call a Python function, they need to learn how to use CGo and how to call C.\nNext, the developer needs to write a C module to connect to Python, either by loading Python or using another FFI library like Boost.Python. The level of expertise and overhead to cross-linking Go to Python is enormous, which many times raises the dilemma if calling Python in the first place justifies the effort, or porting the Python code is more effortless. This problem worsens when multiple languages are involved.\\\nIn the general case, if a developer wishes to use N languages:\n1. In the worst case, as we can see in the figure below in (a) when all n languages are calling each other, n(n − 1) different FFI mechanisms are required for the developer to learn and maintain. The edges in the graph (a) describe the FFI libraries connecting 2 languages represented by nodes. The graph shows that links between all languages form a clique, meaning, it requires n(n − 1).\n2. Multiple libraries \u0026 APIs - hard to learn, understand, maintain and requires high development effort. As if things are not complicated enough, it is tough to build IDEs and static-analysis tools, which are so in need, to so many different, not understand-able libraries.\n\n![Language FFI Libraries](images/graphs.png)\n\nIn MetaFFI, we are taking a different approach, instead of cross-linking the two languages directly, we are cross-linking them indirectly via XLLR (Cross-Language Linker Runtime), which is a C++ library with C-interface. XLLR acts as a coordinator between the different languages. Thus a language needs to link only to XLLR, and through it, it is linked indirectly to all other languages. By doing so, we accomplish two goals:\n1. Single library \u0026 API - Simple to learn, understand and maintain. One usage for all cross-language calls.\n2. In the worst case, when N languages are calling each other via MetaFFI, the calling graph between all languages forms a star (graph (b)), meaning, it requires an XLLR language implementer to use FFI to/from C.\nTo add support for Java, the implementer doesn't need to know anything about other MetaFFI supported languages. In total, for N languages, only 2N links to the XLLR are required. Notice that an MetaFFI user uses all different links to all other languages by calling a stub in host language that indirectly calls the guest language foreign function.\n\n### Parameters Serialization\nOne of the complex challenges of calling a foreign function is modelling the data types of a foreign language into the host language. MetaFFI takes a different approach by serializing the parameters and the result values into a stream of bytes, which both languages can deserialize into their native data types. In other words, MetaFFI aims to create an ideal \"common data types\" by leveraging well-known serialization, such as Google Protobuf.\n\nAs there is no real \"common data types\" (unfortunately) that are native in many languages, the serialization that uses native data types are used to *convert* from host language data types to guest language data types and vice-versa.\n\n### Generated Files By MetaFFI Compiler\nMetaFFI compiler plugins generate files to support the MetaFFI XLLR runtime to perform the successful cross-language call.\n\n* Code in host language with the following goals:\n    * Stubs in the host language with data types of the host language\n    * Serialization of the parameters\n    * Calling XLLR stating the plugin to be used (i.e. *Python3* or *Go*) and module the foreign function(s) are in\n    * Receive serialized return value of the function. In case of error, return an error or throw an exception\n    * Deserialize the return value to host language data types\n    * Return result \n\n* Executable code in a guest language with the following goals:\n    * Stub to be called from XLLR using FFI passing serialized parameters\n    * If applicable, loading of a module containing foreign function(s)\n    * Deserialize parameters to guest language data types\n    * Call foreign function and receive return values\n    * Serialize return values or handle error\n    * return \"Serialized return values\" or error\n    \n* Serialization code and native data types in the host and guest languages\n    * Being generated by executing the serialization code compiler (e.g. `protoc`)\n\n## Tutorials\n### Examples\nDetailed examples can be found in [examples](../Tests/examples/README.md) directory.\n\n### Add New Language Support (Implement MetaFFI plugin)\nEvery plugin is built out of 2 components:\n1. XLLR - implements `xllr_plugin_interface`\n2. Compiler - implements `compiler_plugin_interface`\n\nThe *example* plugin ([example XLLR](XLLR/example/README.md) \u0026 [example Compiler](CLI/example/README.md)) written in C++, contains the least amount of code for plugin implementation and can be used as a template for implementers. The README.md details what is required to build MetaFFI plugin.\n\nThe *Python3* plugin ([python3 XLLR](XLLR/python3/README.md) \u0026 [python3 Compiler](CLI/python3/README.md)) and *Go* plugin ([go XLLR](../plugin-go/runtime/README.md) \u0026 [go Compiler](../plugin-go/compiler/README.md)) contain details about their implementations and can be used as a basis for new plugin.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetaffi%2Fmetaffi-core","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetaffi%2Fmetaffi-core","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetaffi%2Fmetaffi-core/lists"}