将Haskell lib导出为DLL

Fab*_*der 5 dll excel vba haskell ghc

我使用的是GHC版本7.6.1,请按照文档中从Haskell库创建DLL以便在VBA中使用DLL的步骤进行操作: GHC Docs 7.6.1#创建一个DLL

我使用的文件与文档中的文件完全相同。关于编译,命令的以下内容几乎可以按预期工作:

ghc -c Adder.hs
ghc -c StartEnd.c
Run Code Online (Sandbox Code Playgroud)

第一条命令返回以下内容:

Adder.hs:7:1: Warning:
    the 'stdcall' calling convention is unsupported on this platform,
    treating as ccall
    When checking declaration:
      foreign export stdcall "adder" adder :: Int -> Int -> IO Int
Run Code Online (Sandbox Code Playgroud)

我猜应该没问题...

但是,最后一条命令ghc -shared -o Adder.dll Adder.o Adder_stub.o StartEnd.o会产生此错误:

Adder_stub.h:1:19:  fatal error: HsFFI.h: No such file or directory
compilation terminated.
Run Code Online (Sandbox Code Playgroud)

该线程使我认识到GHC没有使用其中的头文件GHC-HOME/lib/include。此线程中的解决方案是将GHC与该选项一起使用-I [path to include-folder],但是,在尝试使用该版本(并查看man和docs)时,此版本的GHC没有此类选项。在8.4.3之前的更新版本中也没有。

阅读本文档时,我还遇到了可以mk-dll在Windows下使用该选项生成dll的可能性。但是,根据我安装的GHC的手册页,即使下载并安装了Windows 64位安装程序,也没有这种选择。

然后,我尝试将include文件夹复制到其他位置。将第三个编译命令所需的文件也复制到该文件夹​​中,然后再次尝试。它成功编译了DLL。

但是,当我尝试从Excel(启用宏的工作簿)中使用DLL时,出现未找到错误DLL的错误。尝试在excel中引用DLL时(通过“工具”->“参考”->“浏览”->“ chooseDll”),它告诉我无法添加DLL。

用DependencyWalker检查DLL,我收到此错误:

Error: At least one required implicit or forwarded dependency was not found.
Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.
Error: Modules with different CPU types were found.
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.
Run Code Online (Sandbox Code Playgroud)

您对如何解决这个问题有任何想法吗?非常感谢...

更新资料

当我尝试使用docs中所述的C ++编译库时,出现以下错误消息:

PS C:\Users\dev\programming\excel_haskell_binding> ghc -o tester.exe .\Tester.cpp .\include\Adder.dll.a
C:\Users\dev\AppData\Local\Temp\ghc4088_0\ghc4088_0.o:ghc4088_0.c:(.text+0x0): multiple definition of `main'
Tester.o:Tester.cpp:(.text+0x0): first defined here
C:\Users\dev\AppData\Local\Temp\ghc4088_0\ghc4088_0.o:ghc4088_0.c:(.text+0x4f): undefined reference to `ZCMain_main_closure'
c:/ghc/ghc-7.6.1/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.6.3/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\dev\AppData\Local\Temp\ghc4088_0\ghc4088_0.o: bad reloc address 0x0 in section `.pdata'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

更新2

我也在尝试另一种方法;看到这个问题GHC编译DLL在VBA中使用

小智 5

我当时正为同样的问题而苦苦挣扎,但是经过长时间的战斗,我设法从64位Excel中运行了该命令。跟着这些步骤:

1)创建Adder.hs(注意ccall,而不是stdcall):

{-# LANGUAGE ForeignFunctionInterface #-}
module Adder where

adder :: Int -> Int -> IO Int  -- gratuitous use of IO
adder x y = return (x+y)

foreign export ccall adder :: Int -> Int -> IO Int
Run Code Online (Sandbox Code Playgroud)

2)创建StartEnd.c:

#include <Rts.h>

void HsStart()
{
   int argc = 1;
   char* argv[] = {"ghcDll", NULL}; // argv must end with NULL

   // Initialize Haskell runtime
   char** args = argv;
   hs_init(&argc, &args);
}

void HsEnd()
{
   hs_exit();
}
Run Code Online (Sandbox Code Playgroud)

3)编译这些文件:

ghc -c Adder.hs
ghc -c StartEnd.c
Run Code Online (Sandbox Code Playgroud)

4)将以下文件从“ C:\ Program Files \ Haskell Platform \ 8.6.3 \ lib \ include”复制到您的生成文件夹中(请记住将stg / Types.h放入stg文件夹中)。如果愿意,也可以复制/ include文件夹的所有内容:

HsFFI.h
ghcconfig.h
ghcautoconf.h
ghcplatform.h
stg/Types.h
Run Code Online (Sandbox Code Playgroud)

5)创建dll:

ghc -shared -o Adder.dll Adder.o Adder_stub.h StartEnd.o
Run Code Online (Sandbox Code Playgroud)

6)现在打开Excel并使用此宏(在Adder之前先使用HsStart)。记住要链接到您自己的文件夹:

Private Declare PtrSafe Function Adder Lib "C:\Users\User\haskell\Adder.dll" Alias "adder" _
  (ByVal x As Long, ByVal y As Long) As Long

Private Declare PtrSafe Sub HsStart Lib "C:\Users\User\haskell\Adder.dll" ()
Private Declare PtrSafe Sub HsEnd Lib "C:\Users\User\haskell\Adder.dll" ()

Private Sub Document_Close()
HsEnd
End Sub

Private Sub Document_Open()
HsStart
End Sub

Public Sub Test()
MsgBox "12 + 5 = " & Adder(12, 5)
End Sub
Run Code Online (Sandbox Code Playgroud)

7)惊奇!