All Projects → wavewave → Fficxx

wavewave / Fficxx

Haskell-C++ Foreign Function Interface Generator

Programming Languages

haskell
3896 projects
cplusplus
227 projects

Projects that are alternatives of or similar to Fficxx

gpgme
GPGme bindings for Rust
Stars: ✭ 55 (-52.99%)
Mutual labels:  wrapper, ffi
haskell-libui
Haskell bindings to the libui C library.
Stars: ✭ 45 (-61.54%)
Mutual labels:  wrapper, ffi
Pokebase
Python 3 wrapper for Pokéapi v2
Stars: ✭ 99 (-15.38%)
Mutual labels:  wrapper
Lzmq
Lua binding to ZeroMQ
Stars: ✭ 110 (-5.98%)
Mutual labels:  ffi
Derry
A script manager for Dart.
Stars: ✭ 107 (-8.55%)
Mutual labels:  ffi
Pynlp
A pythonic wrapper for Stanford CoreNLP.
Stars: ✭ 103 (-11.97%)
Mutual labels:  wrapper
Sdl2 nim
Wrapper of the SDL 2 library for the Nim language.
Stars: ✭ 108 (-7.69%)
Mutual labels:  wrapper
Binance.api.csharp.client
C#.NET client for Binance Exchange API.
Stars: ✭ 98 (-16.24%)
Mutual labels:  wrapper
Wgpu Rs
Rust bindings to wgpu native library
Stars: ✭ 1,694 (+1347.86%)
Mutual labels:  wrapper
Zubr
Wrapper library to fix inconsistencies in PHP's core functions
Stars: ✭ 105 (-10.26%)
Mutual labels:  wrapper
Pokekotlin
Kotlin (or Java, Scala, etc) client for PokeApi
Stars: ✭ 110 (-5.98%)
Mutual labels:  wrapper
Quickjspp
QuickJS C++ wrapper
Stars: ✭ 105 (-10.26%)
Mutual labels:  wrapper
Coinbasepro Python
The unofficial Python client for the Coinbase Pro API
Stars: ✭ 1,386 (+1084.62%)
Mutual labels:  wrapper
Pymiere
Python for Premiere pro
Stars: ✭ 110 (-5.98%)
Mutual labels:  wrapper
Binancedotnet
Official C# Wrapper for the Binance exchange API, with REST and WebSocket endpoints
Stars: ✭ 102 (-12.82%)
Mutual labels:  wrapper
Maxwell
Maxwell is an HTTP client which support for middleware and multiple adapters.
Stars: ✭ 111 (-5.13%)
Mutual labels:  wrapper
Zebra database
A compact, lightweight and feature-rich PHP MySQLi database wrapper
Stars: ✭ 98 (-16.24%)
Mutual labels:  wrapper
Faker Cli
cli wrapper for fakerjs
Stars: ✭ 104 (-11.11%)
Mutual labels:  wrapper
Edafa
Test Time Augmentation (TTA) wrapper for computer vision tasks: segmentation, classification, super-resolution, ... etc.
Stars: ✭ 107 (-8.55%)
Mutual labels:  wrapper
Airtable Php
A PHP client for the Airtable API
Stars: ✭ 115 (-1.71%)
Mutual labels:  wrapper

What is fficxx?

fficxx ("eff fix") is an automatic haskell Foreign Function Interface (FFI) generator to C++.

To 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.

While 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.

Public Haskell-C++ binding generated by fficxx are now collected in fficxx-projects.

fficxx is separated into generator part and runtime part:

  • fficxx : FFI types and binding generator library
  • fficxx-runtime : runtime modules needed for various common routines

Haskell packages that are generated from fficxx will be dependent on fficxx-runtime.

In addition, C++ standard library under std namespace is being generated as a package from fficxx.

  • stdcxx: generated by ./stdcxx-gen/Gen.hs

Getting Started

fficxx is mainly packaged in nix. shell.nix is for development,

nix-shell shell.nix

and use.nix is for using the generated binding package.

nix-shell use.nix

For all build,

nix-build release.nix

OOP Model in fficxx

fficxx 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).

Assuming 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.

data RawA

newtype A = A (ForeignPtr RawA)

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.

Therefore, 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

foo :: A -> CInt -> IO ()

which is a wrapper for a raw level FFI call defined by

foriegn import ccall "A_foo" c_foo :: Ptr RawA -> CInt -> IO ()

where A_foo is a generated C shim function for A::foo. So one can translate the following C++ code

A* a = new A();
a->foo(3);

to the haskell code (in do-block of IO monad)

do a <- newA
   foo a 3

Haskell 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

bar :: A -> A -> IO ()

for which x->bar(y) (x,y are of class A) corresponds to bar x y.

In this example, the C++ class A may have the following declaration:

class A
{
  public:
    A();
    virtual void foo( int );
    virtual void bar( A* );
};

To reflect subtype relations, fficxx creates an interface typeclass IA for A, which is defined as

class IA a where
  foo :: a -> CInt -> IO ()
  bar :: (IA b) => a -> b -> IO ()

which declares all C++ virtual functions as members. Then, haskell type A is a typeclass instance of IA:

instance IA A where
  -- foo :: A -> CInt -> IO ()
  foo = ...
  -- bar :: (IA b) => A -> b -> IO ()
  bar = ...

so that foo and bar functions we considered in the above example were actually defined in the IA instance definition of A. Note that the type signature of bar allows generic typeclass instances of IA as the argument (paraterized by b).

Now consider another C++ class B which is a subclass of A:

class B : public A
{
  public:
    B();
    virtual int baz() ;
}

Again, we will have a concrete haskell type B and an object of B will be created as a value from the newB constructor function. A typeclass IB is also generated as well, and it reflects the inheritance relationship for C++ class as constraints:

class (IA b) => IB b where
  baz :: b -> IO CInt

Thanks to the constraints (IA b) => in the declaration, every instance of IB must have implementation of IA. This is true for B, too. So fficxx generates

instance IA B where
  foo = ...
  bar = ...

instance IB B where
  baz = ...

This 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.

Real World Usage

For the time being, to see how to use generated haskell library, check examples for HROOT : http://ianwookim.org/HROOT/gallery.html (if you click examples, then you can see the source code for them. )

C Macro tricks

We use C Macro tricks described in the following:

C++ Template tricks

C++ Template Peculiarity

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].