{"id":15645282,"url":"https://github.com/thelartians/glue","last_synced_at":"2025-08-07T07:23:56.601Z","repository":{"id":55728687,"uuid":"138604608","full_name":"TheLartians/Glue","owner":"TheLartians","description":"⛓️ Bindings that stick. A simple and generic API for C++ to other language bindings supporting bidirectional communication, inheritance and automatic declarations.","archived":false,"fork":false,"pushed_at":"2020-12-12T21:10:22.000Z","size":1535,"stargazers_count":57,"open_issues_count":2,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-30T10:43:37.144Z","etag":null,"topics":["automatic","bindings","cpp","declarations","glue","inheritance","language-bindings","multi-language","scripting-language","typescript"],"latest_commit_sha":null,"homepage":"","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/TheLartians.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-06-25T14:16:14.000Z","updated_at":"2024-10-26T03:24:02.000Z","dependencies_parsed_at":"2022-08-15T06:40:21.620Z","dependency_job_id":null,"html_url":"https://github.com/TheLartians/Glue","commit_stats":null,"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheLartians%2FGlue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheLartians%2FGlue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheLartians%2FGlue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheLartians%2FGlue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TheLartians","download_url":"https://codeload.github.com/TheLartians/Glue/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251684937,"owners_count":21627213,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["automatic","bindings","cpp","declarations","glue","inheritance","language-bindings","multi-language","scripting-language","typescript"],"created_at":"2024-10-03T12:05:42.827Z","updated_at":"2025-04-30T10:43:50.418Z","avatar_url":"https://github.com/TheLartians.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Actions Status](https://github.com/TheLartians/Glue/workflows/MacOS/badge.svg)](https://github.com/TheLartians/Glue/actions)\n[![Actions Status](https://github.com/TheLartians/Glue/workflows/Windows/badge.svg)](https://github.com/TheLartians/Glue/actions)\n[![Actions Status](https://github.com/TheLartians/Glue/workflows/Ubuntu/badge.svg)](https://github.com/TheLartians/Glue/actions)\n[![Actions Status](https://github.com/TheLartians/Glue/workflows/Style/badge.svg)](https://github.com/TheLartians/Glue/actions)\n[![Actions Status](https://github.com/TheLartians/Glue/workflows/Install/badge.svg)](https://github.com/TheLartians/Glue/actions)\n[![codecov](https://codecov.io/gh/TheLartians/Glue/branch/master/graph/badge.svg)](https://codecov.io/gh/TheLartians/Glue)\n\n# Glue\n\nA common interface for C++ to other language bindings.\n\n## Motivation\n\nC++ is a great language for writing algorithms and high-performance code. \nHowever, once it comes to building applications, servers or websites, simple things become complex and we settle for a scripting language to glue C++ components together.\nThe bindings usually need to be hand-crafted for every exposed type and language.\nThis project aims to create a generic language binding interface in pure standard C++, which allows two-way interactions, automatic declaration creation and relatively short compile times.\n\n## API\n\n### Maps and values\n\nGlue is based on the [Revisited framework](https://github.com/thelartians/Revisited) and provides convenient wrapper methods.\nThe most important types for creating the API and are `glue::Value` and `glue::MapValue`.\n\n```cpp\n#include \u003cglue/value.h\u003e\n#include \u003ciostream\u003e\n\nvoid valueExample() {\n  // `glue::Value`s hold an `revisited::Any` type that can store any type of value\n  glue::Value value = \"Hello glue!\";\n\n  // access the any type through the `-\u003e` or `*` operator\n  // `as\u003cT\u003e()` returns an `std::optional\u003cT\u003e` that is defined if the cast is possible\n  std::cout \u003c\u003c *value-\u003eas\u003cstd::string\u003e() \u003c\u003c std::endl;\n\n  // `glue::MapValue` is a wrapper for a container that maps strings to values\n  // `glue::createAnyMap()` creates a map based on `std::unordered_set`\n  // Values also accept lambda functions\n  glue::MapValue map = glue::createAnyMap();\n  map[\"myNumber\"] = 42;\n  map[\"myString\"] = value;\n  map[\"myCallback\"] = [](bool a, float b){ return a ? b : -b; };\n  map[\"myMap\"] = glue::createAnyMap();\n\n  // use helper functions to cast to maps or callbacks.\n  // the result will evaluate to `false` if no cast is possible.\n  if (auto f = map[\"myCallback\"].asFunction()) {\n    // callbacks are stored as a `revisited::AnyFunction` and can accept both values or `Any` arguments\n    // (here `map[\"myNumber\"]` is casted to an `Any` through the `*` operator)\n    // `get\u003cT\u003e` returns casts the value to `T` or throws an exception if not possible\n    std::cout \u003c\u003c f(false, *map[\"myNumber\"]).get\u003cint\u003e() \u003c\u003c std::endl;\n  }\n\n  // inner maps are also `glue::MapValue`s.\n  map[\"myMap\"].asMap()[\"inner\"] = \"inner value\";\n}\n```\n\n### Classes\n\nGlue also has built-in support for maps representing classes and inheritance.\n\n```cpp\n#include \u003cglue/class.h\u003e\n#include \u003cglue/context.h\u003e\n#include \u003ciostream\u003e\n\nstruct A {\n  std::string member;\n};\n\nstruct B: public A {\n  B(std::string value) : A{value} {}\n  int method(int v) { return int(member.size()) + v; }\n};\n\nvoid classExample() {\n  auto map = glue::createAnyMap();\n\n  // `glue::createClass\u003cT\u003e` is a convience function for declaring maps for class APIs\n  // `addConstructor\u003cArgs...\u003e()` adds a function that constructs `A` given the argument types `Args...`\n  // `.addMember(\"name\", \u0026T::member)` adds a setter (`member`) and getter (`setMember`) function\n  map[\"A\"] = glue::createClass\u003cA\u003e()\n    .addConstructor\u003c\u003e()\n    .addMember(\"member\", \u0026A::member)\n  ;\n\n  // classes can be made inheritance aware\n  // `setExtends(map)` uses the argument map or callback to retrieve undefined keys\n  // `glue::WithBases\u003cA\u003e()` adds implicit conversions to the listed base classes\n  // `addMethod(\"name\", \u0026T::method)` adds a method that calls a member function or lambda\n  map[\"B\"] = glue::createClass\u003cB\u003e(glue::WithBases\u003cA\u003e())\n    .setExtends(map[\"A\"])\n    .addConstructor\u003cstd::string\u003e()\n    .addMethod(\"method\", \u0026B::method)\n    .addMethod(\"lambda\", [](const B \u0026b, int x){ return b.member.size() + x; })\n  ;\n\n  // contexts collect map class data and can be used to test instance creation\n  glue::Context context;\n  context.addRootMap(map);\n\n  // `glue::Instance` captures a value and behaves as a class instance\n  auto b = context.createInstance(map[\"B\"][glue::keys::constructorKey](\"arg\"));\n\n  // calls will be treated as member functions\n  std::cout \u003c\u003c b[\"member\"]().get\u003cstd::string\u003e() \u003c\u003c std::endl;\n  b[\"setMember\"](\"new value\");\n  std::cout \u003c\u003c b[\"lambda\"](10).get\u003cint\u003e() \u003c\u003c std::endl;\n}\n```\n\n### Declarations\n\nGlue can automatically generate declarations for type-safe scripting using TypeScript or [TypeScriptToLua](https://typescripttolua.github.io).\n\n```cpp\nglue::DeclarationPrinter printer;\nprinter.init();\nprinter.print(std::cout, map, \u0026context);\n```\n\nIn the example above, this would result in the following declarations.\n\n```ts\n/** @customConstructor A.__new */\ndeclare class A {\n  constructor()\n  member(): string\n  setMember(arg1: string): void\n}\n/** @customConstructor B.__new */\ndeclare class B extends A {\n  constructor(arg0: string)\n  lambda(arg1: number): number\n  method(arg1: number): number\n}\n```\n\n## Supported bindings\n\nHere you can find current and planned bindings for Glue.\n\n- [x] Lua: [LuaGlue](https://github.com/TheLartians/LuaGlue)\n- [x] JavaScript (Wasm): [EmGlue](https://github.com/TheLartians/EmGlue)\n- [ ] JavaScript (Duktape)\n- [ ] Python\n- [ ] Java\n- [ ] Swift\n- [ ] Rust\n\nAs you can see, many bindings are still missing from the list.\nIf you've created Glue bindings for any language, feel free to open a PR to add them here.\n\n## Limitations\n\n- No support for pointer or optional arguments in callbacks (yet)\n- Class bindings aren't as sophisticated as other libraries bindings such as [sol2](https://github.com/ThePhD/sol2)\n- There is a small overhead through the additional abstraction layer compared to native bindings\n\n## Usage\n\nGlue can be easily added to your project using [CPM.cmake](https://github.com/TheLartians/CPM.cmake).\n\n```cmake\nCPMAddPackage(\n  NAME Glue\n  VERSION 1.0\n  GIT_REPOSITORY https://github.com/TheLartians/Glue.git\n)\n\ntarget_link_libraries(myLibrary Glue)\n```\n\nSee [here](https://github.com/TheLartians/TypeScriptXX) for an example project using Glue to create TypeScript bindings for C++.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthelartians%2Fglue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthelartians%2Fglue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthelartians%2Fglue/lists"}