Skip to content

Instantly share code, notes, and snippets.

@sighingnow
Last active December 27, 2016 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sighingnow/ee989ef541f4d6ec323d79da2ba8a181 to your computer and use it in GitHub Desktop.
Save sighingnow/ee989ef541f4d6ec323d79da2ba8a181 to your computer and use it in GitHub Desktop.
Expose C++ API to Haskell via FFI.
#include <iostream>
#include "acpp.h"
using namespace std;
A::A(int v): _v(v) {
std::cout << "Construct A, value: " << _v << std::endl;
}
void A::job(int arg) {
std::cout << "Execute job in A, arg: " << arg << std::endl;
}
A::~A() {
std::cout << "Destruct A" << std::endl;
}
#ifndef __ACPP_H__
#define __ACPP_H__
#ifdef __cplusplus
class A {
public:
A(int v);
void job(int arg);
~A();
public:
int _v;
};
#endif // !__cplusplus
#endif // !__ACPP_H__
#include "acpp_capi.h"
APtr makeA(int a) {
return new A(a);
}
void jobA(APtr aptr, int arg) {
aptr->job(arg);
}
void freeA(APtr aptr) {
delete aptr;
}
#ifndef __ACPP_CAPI_H__
#define __ACPP_CAPI_H__
#include "acpp.h"
#ifdef __cplusplus
extern "C" {
typedef A *APtr;
#else
typedef void *APtr; // dummy type.
#endif
APtr makeA(int v);
void jobA(APtr aptr, int arg);
void freeA(APtr aptr);
#ifdef __cplusplus
}
#endif
#endif // !__ACPP_CAPI_H__
import Foreign.C.Types
import Foreign.Ptr
main :: IO ()
main = do
a <- makeA 1234
jobA a 5678
freeA a
-- | Here @Ptr ()@ is a dummy type, means @class A *@ in C++.
foreign import ccall unsafe "acpp_capi.h makeA" makeA :: CInt -> IO (Ptr ())
foreign import ccall unsafe "acpp_capi.h jobA" jobA :: Ptr () -> CInt -> IO (Ptr ())
foreign import ccall unsafe "acpp_capi.h freeA" freeA :: Ptr () -> IO ()
all: libacpp.dll app.exe
GHC := stack ghc --
%.o: %.cpp
$(CXX) -c $< -o $@
libacpp.dll: acpp.o acpp_capi.o
$(CXX) $^ -shared -o $@ # On Linux/Unix, -fPIC is needed.
app.exe: app.hs acpp_capi.h libacpp.dll
$(GHC) $< -lacpp -o $@
clean:
$(RM) -f *.o *.exe *.hi
.PNONY: clean
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment