{"id":17235542,"url":"https://github.com/wavewave/fficxx","last_synced_at":"2025-04-09T14:15:14.106Z","repository":{"id":1836038,"uuid":"2760413","full_name":"wavewave/fficxx","owner":"wavewave","description":"Haskell-C++ Foreign Function Interface Generator","archived":false,"fork":false,"pushed_at":"2023-08-30T18:55:32.000Z","size":5901,"stargazers_count":143,"open_issues_count":42,"forks_count":13,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-02T08:57:01.778Z","etag":null,"topics":["cplusplus","ffi","haskell","haskell-libraries","wrapper"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"torch/torch7","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wavewave.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2011-11-12T05:39:10.000Z","updated_at":"2025-03-23T13:44:22.000Z","dependencies_parsed_at":"2025-01-01T07:03:01.714Z","dependency_job_id":null,"html_url":"https://github.com/wavewave/fficxx","commit_stats":{"total_commits":937,"total_committers":6,"mean_commits":"156.16666666666666","dds":"0.016008537886872953","last_synced_commit":"a0808b2daa1d1ed6d1c1c5cef265bdff9b937910"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wavewave%2Ffficxx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wavewave%2Ffficxx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wavewave%2Ffficxx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wavewave%2Ffficxx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wavewave","download_url":"https://codeload.github.com/wavewave/fficxx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248054193,"owners_count":21039952,"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":["cplusplus","ffi","haskell","haskell-libraries","wrapper"],"created_at":"2024-10-15T05:33:52.234Z","updated_at":"2025-04-09T14:15:14.076Z","avatar_url":"https://github.com/wavewave.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"What is fficxx?\n===============\n\n![Build](https://github.com/wavewave/fficxx/actions/workflows/build.yml/badge.svg)\n\nfficxx (\"eff fix\") is an automatic haskell Foreign Function Interface (FFI) generator to C++.\n\nTo use fficxx, you write a Haskell model of the C++ public interfaces and fficxx generates both a C wrapper and associated haskell functions and type classes which reflect specified model of the C++ interfaces. It is currently the user's responsibility to specify a correct model of the C++ interfaces, because fficxx does not presently check for model correctness.\n\nWhile haskell has a well-specified standard for C FFI, making haskell-C++ FFI is an arbitrary and painful process. Since Object-Oriented Programming (OOP) paradigm and Functional Programming (FP) paradigm are different, automatic translation of C++ libraries to haskell libraries is not a straightforward task. The goal of fficxx is to minimize this disparity and maximize user's convenience by providing familiar interface to the original C++ library as a result.\n\nPublic Haskell-C++ binding generated by fficxx are now collected in [fficxx-projects](https://github.com/wavewave/fficxx-projects).\n\nfficxx is separated into generator part and runtime part:\n\n* fficxx : FFI types and binding generator library\n* fficxx-runtime : runtime modules needed for various common routines\n\nHaskell packages that are generated from fficxx will be dependent on fficxx-runtime.\n\nIn addition, C++ standard library under `std` namespace is being generated as a package from fficxx.\n* stdcxx: generated by ./stdcxx-gen/Gen.hs\n\n\nGetting Started\n===============\n\nfficxx is mainly packaged in nix.\n`shell.nix` is for development,\n```\nnix-shell shell.nix\n```\nand `use.nix` is for using the generated binding package.\n```\nnix-shell use.nix\n```\n\nFor all build,\n```\nnix-build release.nix\n```\n\n\n\nOOP Model in fficxx\n===================\n\nfficxx generates haskell codes at raw level (C wrapper and haskell foreign pointer  that are directly matched with C/C++ types) and at high level (newtype wrapper for raw level pointer and haskell typeclasses reflecting OOP class hierarchy). Haskell does not have a concept of subtyping, i.e. we do not provide any easy way to create a new subclass and overload member functions from existing classes on haskell side. However, fortunately, one can describe the OOP subclass relationship using a typeclass interface as a contract for a class `b` to be equal to or a subclass of `a`. In a sense, typeclasses are Interface Definition Language (IDL) for describing OOP classes. Thus, a C++ class is represented by both haskell concrete type (for a C++ class itself) and typeclass (a set of classes that can be equal to or a subclass of the C++ class).\n\nAssuming that there is a C++ class `A`. fficxx generates a haskell type `A`. This haskell type `A` is nothing but a newtype wrapping `ForeignPtr` tagged by `RawA`.\n```\ndata RawA\n\nnewtype A = A (ForeignPtr RawA)\n```\n`RawA` exists only for the purpose of a phantom type to be used as tags for `Ptr` in FFI imports (`foreign import` statements.) When programming with fficxx-generated code at high level, programmers should seldom encounter `Raw` types. An instance object of C++ class `A` is a value of haskell type `A`. To create an instance, fficxx provides a smart constructor (`newA`) if specified with a corresponding constructor.\n\nTherefore, one can create an instance from a concrete haskell type, and pass it to any functions which needs them. On Haskell side, member functions of a C++ class are nothing but functions whose first argument is the same as the corresponding haskell type to the class. For example, if the class `A` has a member function `foo` of signature `void A::foo( int param )`, then fficxx generates a high level function\n```\nfoo :: A -\u003e CInt -\u003e IO ()\n```\nwhich is a wrapper for a raw level FFI call defined by\n```\nforiegn import ccall \"A_foo\" c_foo :: Ptr RawA -\u003e CInt -\u003e IO ()\n```\nwhere `A_foo` is a generated C shim function for `A::foo`. So one can translate the following C++ code\n```\nA* a = new A();\na-\u003efoo(3);\n```\nto the haskell code (in do-block of IO monad)\n```\ndo a \u003c- newA\n   foo a 3\n```\nHaskell type `A` can be used in the arbitrary argument position. Assume there is another member function `bar` of `A` which takes an object of `A` as an argument like `void A::bar( A* a )`. Then, we have\n```\nbar :: A -\u003e A -\u003e IO ()\n```\nfor which `x-\u003ebar(y)` (`x`,`y` are of class `A`) corresponds to `bar x y`.\n\nIn this example, the C++ class `A` may have the following declaration:\n```\nclass A\n{\n  public:\n    A();\n    virtual void foo( int );\n    virtual void bar( A* );\n};\n```\nTo reflect subtype relations, fficxx creates an interface typeclass `IA` for `A`, which is defined as\n```\nclass IA a where\n  foo :: a -\u003e CInt -\u003e IO ()\n  bar :: (IA b) =\u003e a -\u003e b -\u003e IO ()\n```\nwhich declares all C++ virtual functions as members. Then, haskell type `A` is a typeclass instance of `IA`:\n```\ninstance IA A where\n  -- foo :: A -\u003e CInt -\u003e IO ()\n  foo = ...\n  -- bar :: (IA b) =\u003e A -\u003e b -\u003e IO ()\n  bar = ...\n```\nso that `foo` and `bar` functions we considered in the above example were actually defined in the `IA` instance definition of A.\nNote that the type signature of `bar` allows generic typeclass instances of `IA` as the argument (paraterized by `b`).\n\nNow consider another C++ class `B` which is a subclass of `A`:\n```\nclass B : public A\n{\n  public:\n    B();\n    virtual int baz() ;\n}\n```\nAgain, we will have a concrete haskell type `B` and an object of `B` will be created as a value from the `newB` constructor function.\nA typeclass `IB` is also generated as well, and it reflects the inheritance relationship for C++ class as constraints:\n```\nclass (IA b) =\u003e IB b where\n  baz :: b -\u003e IO CInt\n```\nThanks to the constraints `(IA b) =\u003e` in the declaration, every instance of `IB` must have implementation of `IA`. This is true for `B`, too.\nSo fficxx generates\n```\ninstance IA B where\n  foo = ...\n  bar = ...\n\ninstance IB B where\n  baz = ...\n```\nThis instance generation (*implemenation of C++ class*) is automaticaly done by fficxx, but it's not guaranteed for future subclassing. Any type which implements instances of `IA` and `IB` can be regarded as a subclass of `B`, but it's not automatically done as we have in OOP. The scope of fficxx is to generate such implementations only for existing C++ classes.\n\nReferences\n==========\n\n## C Macro tricks\n\nWe use C Macro tricks described in the following:\n* http://jhnet.co.uk/articles/cpp_magic\n* https://stackoverflow.com/questions/45585903/c-macros-how-to-map-another-macro-to-variadic-arguments\n* https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms\n* https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/\n* https://stackoverflow.com/questions/3046889/optional-parameters-with-c-macros/3048361#3048361\n\n## C++ Template tricks\n\n* https://en.cppreference.com/w/cpp/language/template_argument_deduction\n* http://anderberg.me/2016/08/01/c-variadic-templates/\n* https://crascit.com/2015/03/21/practical-uses-for-variadic-templates/\n\n## C++ Template Peculiarity\n\n* https://stackoverflow.com/questions/2354210/can-a-c-class-member-function-template-be-virtual\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwavewave%2Ffficxx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwavewave%2Ffficxx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwavewave%2Ffficxx/lists"}