{"id":17342915,"url":"https://github.com/haxiomic/haxe-c-bridge","last_synced_at":"2025-10-20T00:48:31.786Z","repository":{"id":39967088,"uuid":"325690298","full_name":"haxiomic/haxe-c-bridge","owner":"haxiomic","description":"Easily interact with haxe classes from C with an automatically generated C header","archived":false,"fork":false,"pushed_at":"2025-05-11T13:43:05.000Z","size":336,"stargazers_count":54,"open_issues_count":8,"forks_count":5,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-07-24T13:29:12.702Z","etag":null,"topics":["android","c","cross-platform","embed","embed-haxe","exposed-functions","gamedev","haxe","haxe-thread","hxcpp","interop","ios","windows"],"latest_commit_sha":null,"homepage":"","language":"Haxe","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/haxiomic.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-12-31T02:02:51.000Z","updated_at":"2025-07-03T09:28:16.000Z","dependencies_parsed_at":"2025-07-24T11:28:19.197Z","dependency_job_id":"af428dc8-9d6c-45c3-99fc-8b86c22244e2","html_url":"https://github.com/haxiomic/haxe-c-bridge","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/haxiomic/haxe-c-bridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haxiomic%2Fhaxe-c-bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haxiomic%2Fhaxe-c-bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haxiomic%2Fhaxe-c-bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haxiomic%2Fhaxe-c-bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/haxiomic","download_url":"https://codeload.github.com/haxiomic/haxe-c-bridge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haxiomic%2Fhaxe-c-bridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279960303,"owners_count":26251359,"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","status":"online","status_checked_at":"2025-10-19T02:00:07.647Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["android","c","cross-platform","embed","embed-haxe","exposed-functions","gamedev","haxe","haxe-thread","hxcpp","interop","ios","windows"],"created_at":"2024-10-15T16:07:29.201Z","updated_at":"2025-10-20T00:48:31.765Z","avatar_url":"https://github.com/haxiomic.png","language":"Haxe","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Haxe C Bridge\n\nHaxeCBridge is a `@:build` macro that enables calling haxe code from C by exposing classes via an automatically generated C header. This makes it possible to build your user interfaces using native platform tools (like Swift and Java) and call into haxe code for the main app work like rendering\n\n**Requires haxe 4.0 or newer and hxcpp**\n\n## Quick Start\n\nInstall with `haxelib install haxe-c-bridge` (or simply copy the `HaxeCBridge.hx` file into your root class-path)\n\nHaxe-side:\n- Add `--library haxe-c-bridge` to your hxml\n- Add `-D dll_link` or `-D static_link` to your hxml to compile your haxe program into a native library binary\n- Add `@:build(HaxeCBridge.expose())` to classes that you want to expose to C (you can add this to as many classes as you like – all functions are combined into a single header file)\n- HaxeCBridge will then generate a header file in your build output directory named after your `--main` class (however a `--main` class is not required to use HaxeCBridge)\n\nC-side:\n- `#include` the generated header and link with the hxcpp generated library binary\n- Before calling any haxe functions you must start the haxe thread: call `YourLibName_initializeHaxeThread(onHaxeException)`\n- Now interact with your haxe library thread by calling the exposed functions\n- When your program exits call `YourLibName_stopHaxeThread(true)`\n\nSee [test/unit](test/unit) for a complete example\n\n## Minimal Example\n\n**Main.hx**\n```haxe\nclass Main {\n\tstatic function main() {\n\t\ttrace(\"haxe thread started!\");\n\t}\n}\n\n@:build(HaxeCBridge.expose())\nclass UseMeFromC {\n\n\tfinal callback: cpp.Callable\u003c(num: Int) -\u003e Void\u003e;\n\n\tpublic function new(nativeCallback: cpp.Callable\u003c(num: Int) -\u003e Void\u003e) {\n\t\tthis.callback = nativeCallback;\n\t}\n\n\tpublic function add(a: Int, b: Int) {\n\t\tvar result = a + b;\n\t\tcallback(result);\n\t\treturn result;\n\t}\n\n\tstatic public function exampleStaticFunction() {\n\t\treturn \"here's a string from haxe! In C this will be represented as a const char*. When passing haxe object to C, the object will be retained so it's not garbage collected while it's being used in C. When finished with haxe objects, you can call releaseHaxeString() or releaseHaxeObject()\";\n\t}\n\n}\n```\n\n**build.hxml**\n```hxml\n--main Main\n--cpp bin\n--dce full\n-D dll_link\n```\n\nThen run `haxe build.hxml` to compile the haxe code into a native library binary\n\nThis will generate a header file: `bin/Main.h` with our haxe function exposed as:\n```C\nHaxeObject Main_UseMeFromC_new(function_Int_Void exampleCallback);\nint Main_UseMeFromC_add(HaxeObject instance, int a, int b);\nHaxeString Main_UseMeFromC_exampleStaticFunction();\n```\n\nWe can use our class from C like so:\n```C\nvoid onHaxeException(const char* info) {\n\tprintf(\"Haxe exception: \\\"%s\\\"\\n\", info);\n\t// stop the haxe thread immediately\n\tMain_stopHaxeThreadIfRunning(false);\n}\n\nvoid exampleCallback(int num) {\n\tprintf(\"exampleCallback(%d)\\n\", num);\n}\n\nint main(void) {\n\t// start the haxe thread\n\tMain_initializeHaxeThread(onHaxeException);\n\n\t// create an instance of our haxe class\n\tHaxeObject instance = Main_UseMeFromC_new(exampleCallback);\n\t// to call members of instance, we pass the instance in as the first argument\n\tint result = Main_UseMeFromC_add(instance, 1, 2);\n\t// when we're done with our object we can tell the haxe-gc we're finished\n\tMain_releaseHaxeObject(instance);\n\n\t// call a static function\n\tHaxeString cStr = Main_UseMeFromC_exampleStaticFunction();\n\tprintf(\"%s\\n\", cStr);\n\tMain_releaseHaxeString(cStr);\n\n\t// stop the haxe thread but wait for any scheduled events to complete\n\tMain_stopHaxeThreadIfRunning(true);\n\n\treturn 0;\n}\n```\n\n## Background\n\nC is a common language many platforms use to glue to one another. It's always been relatively easy to call C code from haxe using haxe C++ externs (or simply [`untyped __cpp__('c-code')`](https://haxe.org/manual/target-syntax.html)) but it's much harder to call haxe code from C: while hxcpp can generate C++ declarations with [`@:nativeGen`](https://github.com/HaxeFoundation/hxcpp/blob/master/test/extern-lib/api/HaxeApi.hx), you need to manually create adaptors for these to use with C. Additionally you have to take care to manage the haxe event loop and interaction with the haxe garbage collector. \n\nThis library plugs that gap by automatically generating safe function bindings, managing the event loop and taking care of converting exposed types to be C compatible and GC-safe.\n\nA separate thread is used to host the haxe execution and the haxe event loop so events scheduled in haxe will continue running in parallel to the rest of your native app. When calling haxe functions from C, the haxe code will be executed synchronously on this haxe thread so it's safe for functions exposed to C to interact with the rest of your haxe code. You can disable haxe thread synchronization by adding `@externalThread` however this is less safe and you must then perform main thread synchronization yourself.\n\n## Meta\n- `@HaxeCBridge.name` – Can be used on functions and classes. On classes it sets the class prefix for each generated function and on functions it sets the complete function name (overriding prefixes)\n- `@externalThread` – Can be used on functions. When calling a haxe function with this metadata from C that function will be executed in the haxe calling thread, rather than the haxe main thread. This is faster but less safe – you cannot interact with any other haxe code without first synchronizing with the haxe main thread (or your app is likely to crash)\n\n## Compiler Defines\n- `-D HaxeCBridge.name=YourLibName` – Set the name of the generated header file as well as the prefix to all generated C types and functions\n- `-D dll_link` – A [hxcpp define](https://haxe.org/manual/target-cpp-defines.html) to compile your haxe code into a dynamic library (.dll, .dylib or .so on windows, mac and linux)\n- `-D static_link` – A [hxcpp define](https://haxe.org/manual/target-cpp-defines.html) to compile your haxe code into a static library (.lib on windows or .a on mac and linux)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaxiomic%2Fhaxe-c-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhaxiomic%2Fhaxe-c-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaxiomic%2Fhaxe-c-bridge/lists"}