reservadas - ¿Cómo usar una DLL en un proyecto Haskell?
peta haskell en español (3)
Necesitará usar
extra-lib-dirs
yextra-libraries
en la secciónexecutable
de su archivo.cabal
de la.cabal
manera:name: MyApp version: 0.1.0.0 synopsis: homepage: author: simon.bourne category: build-type: Simple cabal-version: >=1.10 library exposed-modules: HelloWorld build-depends: base >= 4.7 && < 5 hs-source-dirs: src default-language: Haskell2010 executable MyApp main-is: Main.hs extra-lib-dirs: lib extra-libraries: helloWorld build-depends: base >= 4.7 && < 5, MyApp hs-source-dirs: app default-language: Haskell2010
Pon tu dll y .so en
lib
. Tenga cuidado, se encontrará con problemas de orden de enlace si usa una biblioteca estática (.a
lugar de.so
) en Linux.Mira this para un ejemplo. No se deje engañar por el nombre, ya que funciona bien con los archivos
.so
.stack ghci
solo debería funcionar siempre que pueda encontrar su biblioteca (LD_LIBRARY_PATH
en Linux).La API C (mencionada en los comentarios sobre su pregunta) ya está allí. Solo necesita escribir las firmas Haskell FFI, por ejemplo:
foreign import ccall safe "helloWorld" c_helloWorld :: IO ()
Aconsejo encarecidamente el uso de avisos de
safe
y nounsafePerformIO
las funciones enunsafePerformIO
.Si necesita pasar estructuras no opacas, es posible que desee investigar
c2hs
ohsc2hs
, pero no creo que deba hacerlo. Vea esta question para más detalles.
Me gustaría utilizar una biblioteca externa, RDFox , en un proyecto Haskell.
Contexto: estoy trabajando en Windows y Linux, ambos de 64 bits, usando GHC 7.10 y stack . RDFox está programado en C ++. Las bibliotecas compartidas de RDFox (.dll, .so) se pueden descargar con envoltorios de Java y Python.
Objetivo: me gustaría reutilizar las librerías compiladas de RDFox (.dll, .so) en mi proyecto en Haskell, así que necesito crear un contenedor Haskell para RDFox.
Problemas: Al ser relativamente nuevo en Haskell, tengo dificultades para saber por dónde empezar. Encontré varias páginas sobre el tema (de la wiki de Haskell y StackOverflow), pero el flujo de trabajo y la configuración no son claros para mí.
Preguntas: Me gustaría saber:
- Cómo configurar stack y cabal para usar una biblioteca externa, para construir en Windows o Linux (diferentes máquinas, mismo repositorio).
- Cómo configurar GHCi para pruebas interactivas en esta biblioteca externa.
- ¿La traducción de Python a Haskell es la mejor manera de hacerlo? Me gustaría evitar el análisis del código RDFox C ++.
Debe crear un contenedor C-exportado para la API C ++ y un contenedor Haskell para FFI para C-exported wrapper.
El mapeo entre C # y Haskell se describe aquí: Llamando a Haskell desde C #
pero es muy similar entre C ++ y Haskell
Por ejemplo, crea la función de exportación C ++:
extern "C" __declspec(dllexport) int __cdecl addFive(int number);
extern "C" __declspec(dllexport) int __cdecl addFive(int number)
{
return number + 5;
}
En Haskell necesitas código de importación:
foreign import ccall "addFive" addFive :: Int -> Int
Entonces puedes usar addFive en Haskell como función típica de Haskell
Para tipos de datos compilados (clases y estructuras), necesita crear un análogo de tipo de datos C ++ en Haskell. Luego, necesita describir cómo se clasifican los tipos de datos de C ++ a Haskell y de Haskell a C ++.
En Haskell significa que necesita crear instancias almacenables para sus tipos de datos.
Respuesta de esta documentación :
ghc -c Adder.hs
ghc -c StartEnd.c
ghc -shared -o Adder.dll Adder.o Adder_stub.o StartEnd.o