Last active
December 27, 2016 15:38
-
-
Save sighingnow/ee989ef541f4d6ec323d79da2ba8a181 to your computer and use it in GitHub Desktop.
Expose C++ API to Haskell via FFI.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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