gpt4 book ai didi

visual-studio-2010 - 如何将 Haskell DLL 集成到 C++/Qt Windows 应用程序中?

转载 作者:行者123 更新时间:2023-12-01 13:51:22 24 4
gpt4 key购买 nike

我用 Haskell 编写了一些函数,我想将它们构建到一个 DLL 中,这样我就可以从我的 C++ 应用程序中调用它们。我过得很糟糕。 (似乎从 Haskell 调用 C DLL 更常见,也有更好的文档记录。)

我的 Haskell 安装是 MinGHC 7.10.1(32 位)。 C++项目使用Visual Studio 2010和Qt 5.4;我使用 qmake 从 .pro 文件生成 VS 项目文件。这是我正在做的:

  1. 使用 cabal-install 安装我的图书馆需要的包。 (这些在全局范围内安装,而不是在沙箱中。)
  2. 运行 ghc -no-hs-main -v SpectrumMath.hs > ghc_output 2>&1 将 GHC 的详细构建输出转储到文件中。
  3. 查看 ghc_output 文件并找到链接器命令(它是“*** Linker:”之后的行)。提取库目录(由 -L 标志指示)和库名称(由 -l 标志指示)。
  4. 将这些库添加到 Qt .pro 文件中,例如

    LIBS += \
    -Lsome_long_path_here \
    -Lsome_other_long_path_here \
    -lsome_library_name_here \
    -lsome_other_library_name_here
  5. 运行 ghc --print-libdir。将 /include 附加到此路径的末尾并将其添加到 .pro 文件中:

    INCLUDEPATH += "C:/Program Files (x86)/MinGHC-7.10.1/ghc-7.10.1/lib/include"
  6. 运行 qmake 生成 Visual Studio 项目。

  7. 打开 VS 项目。打开项目的属性并导航到配置属性→链接器→输入并编辑附加依赖项字段。 Qmake 帮助“修复”了库的名称,因此将“HSsomething.lib”的每个实例替换为“libHSsomething.a”。同样,将“Cffi-6.lib”重命名为“libCffi-6.a”,将“HSrts.lib”重命名为“libHSrts.a”。

这个疯狂的过程来自this page在维基上。它假定 C++ 文件将 #include "SpectrumMath_stub.h",这是一个由 GHC 在步骤 2 中生成的文件。

我在这一点上卡住了,因为我不知道如何处理 m 库(来自 -lm 标志的库)。 Visual Studio 找不到“m.lib”,但如果我从列表中删除该库,我会收到许多“未解析的外部”消息,因此需要该库。。如何告知 Visual Studio libm 依赖项?还是我应该完全遵循另一个流程?

最佳答案

我推荐使用 cabal-install (或 stack )实际上是为了这个。如果您计划在没有 LPGL 兼容许可的情况下分发此 DLL,您可能希望使用 integer-simple 构建 GHC而不是 integer-gmp (默认)。


haskell 方面

首先要熟悉this GHC tutorial .

读完之后,您会意识到您需要一份 StartEnd.c某处。假设它在 src\ 中.

所以这是你的 MyLibrary.cabal文件:

...other cabal stuff...

library
exposed-modules: MyModule
--other-modules:
other-extensions: ForeignFunctionInterface
build-depends: base
hs-source-dirs: src
c-sources: src/StartEnd.c --tells cabal to rebuild if this changes
default-language: Haskell2010
--default-extensions:

-- Add whatever options you need, in addition to these:
-- (In my experience, adding `-threaded` can make the DLL
-- behave better during debugging; but that's only a guess.)
ghc-options: -O1 -shared src/StartEnd.c

现在用 cabal build 构建它(或 stack build 如果您使用的是 stack )。

预计会看到警告。 Cabal 不太清楚你在做什么。

您会发现三个与您的 cabal 项目相关的重要文件:

  • HSdll.dll
  • HSdll.dll.a (Windows 正常调用这些 .lib 文件;您可以根据需要重命名)
  • build\...\MyLibrary_stub.h

请注意,此 DLL 静态链接所有 Haskell 依赖项。因此,除了您的 DLL 之外,您不需要告诉 Visual Studio 任何其他信息。


C++ 方面

  • 在您的 C++ 代码中,您需要包含 MyLibrary_stub.h上面生成的文件。
  • 您还需要包括 HsStart 的原型(prototype)和 HsEnd某处:

    extern "C" {
    void HsStart();
    void HsEnd();
    }

  • _stub.h文件包含一些 GHC header ,因此您需要在 VS 项目中的“附加包含”中添加一个文件夹:<ghc-folder>\ghc-7.10.1\lib\include .

    • 执行此操作的一个技巧是运行 where ghc , 下降 ghc.exe , 并追加 \..\lib\include结果。

在您的 C++ 应用程序中,确保调用 HsStart()HsEnd()在程序的开头和结尾。我喜欢将它们封装在 RAII 结构中,这样我就不会忘记做对了。


我的经历

我用 cabal-install 试过了1.2* 版本和 stack .我使用过 GHC 7.8.4 和 7.10.1,每个都有 32 位和 64 位版本。

请注意Cabal即将推出 much better support for this .


命名你的 DLL

在 Cabal 有更好的支持之前,我发现给你的 DLL 命名的唯一方法是添加 -o MyLibrary.dllghc-options .即使它有效,GHC 也会在您执行此操作时向您发出警告,表明它并不真正知道发生了什么。为了解决这个问题,您可以预构建 StartEnd.c进入StartEnd.o并将其链接起来。使用的命令是这样的:

cabal exec -- ghc -optc-O -c src/StartEnd.c -o obj/StartEnd.o

现在,在 ghc-options , 替换 src/StartEnd.cobj/StartEnd.o .

正在替换 cabalstack如果您使用 stack,也应该可以使用.

关于visual-studio-2010 - 如何将 Haskell DLL 集成到 C++/Qt Windows 应用程序中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31438420/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com