将 Haskell 库导出为 DLL
Export Haskell lib as DLL
我正在使用 GHC 版本 7.6.1,按照文档中的步骤从 Haskell 库创建 DLL,以便在 VBA 中使用它:
GHC Docs 7.6.1 # Make a DLL
我使用的文件与文档中的文件完全相同。在编译时,以下命令几乎按预期工作:
ghc -c Adder.hs
ghc -c StartEnd.c
第一个命令returns这个:
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
我想应该没问题...
但是,最后一个命令 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.
让我认识到 GHC 没有使用其 GHC-HOME/lib/include
中的头文件。
该线程中的解决方案是使用带选项 -I [path to include-folder]
的 GHC,但是,在尝试它时(并查看手册和文档),此版本的 GHC 没有这样的选项; 8.4.3 之前的新版本也没有。
的时候reading this docs我也遇到过应该可以使用windows下的选项mk-dll
来生成dll;然而,根据我安装的 GHC 的手册页,没有这样的选项,即使我下载并安装了 windows 64 位安装程序。
然后我尝试将 include 文件夹复制到其他位置;把第三条编译命令需要的文件也复制到文件夹里再试。成功编译DLL;
但是,当我尝试使用 Excel(启用宏)工作簿中的 DLL 时,出现错误 DLL 未找到。当试图在 excel 中引用 DLL 时(通过工具->引用->浏览-> 选择 Dll)它告诉我它不能添加 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.
您对如何解决这个问题有什么想法吗?
非常感谢...
更新
当我尝试使用文档中描述的 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
更新 2
我也在尝试不同的方法;看到这个问题 GHC compile DLL for use in VBA
我一直在为同样的问题而苦苦挣扎,但经过长时间的斗争,我设法 运行 来自 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
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();
}
3) 编译这些文件:
ghc -c Adder.hs
ghc -c StartEnd.c
4) 将以下文件从 "C:\Program Files\Haskell Platform.6.3\lib\include" 复制到您的构建文件夹(记得将 stg/Types.h 放入 stg 文件夹)。如果您愿意,您也可以复制 /include 文件夹中的所有内容:
HsFFI.h
ghcconfig.h
ghcautoconf.h
ghcplatform.h
stg/Types.h
5) 创建dll:
ghc -shared -o Adder.dll Adder.o Adder_stub.h StartEnd.o
6) 现在打开 Excel 并使用这个宏(在 Adder 之前先使用 HsStart)。记得link到你自己的文件夹:
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
7) 惊叹不已!
我正在使用 GHC 版本 7.6.1,按照文档中的步骤从 Haskell 库创建 DLL,以便在 VBA 中使用它: GHC Docs 7.6.1 # Make a DLL
我使用的文件与文档中的文件完全相同。在编译时,以下命令几乎按预期工作:
ghc -c Adder.hs
ghc -c StartEnd.c
第一个命令returns这个:
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
我想应该没问题...
但是,最后一个命令 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.
GHC-HOME/lib/include
中的头文件。
该线程中的解决方案是使用带选项 -I [path to include-folder]
的 GHC,但是,在尝试它时(并查看手册和文档),此版本的 GHC 没有这样的选项; 8.4.3 之前的新版本也没有。
的时候reading this docs我也遇到过应该可以使用windows下的选项mk-dll
来生成dll;然而,根据我安装的 GHC 的手册页,没有这样的选项,即使我下载并安装了 windows 64 位安装程序。
然后我尝试将 include 文件夹复制到其他位置;把第三条编译命令需要的文件也复制到文件夹里再试。成功编译DLL;
但是,当我尝试使用 Excel(启用宏)工作簿中的 DLL 时,出现错误 DLL 未找到。当试图在 excel 中引用 DLL 时(通过工具->引用->浏览-> 选择 Dll)它告诉我它不能添加 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.
您对如何解决这个问题有什么想法吗? 非常感谢...
更新
当我尝试使用文档中描述的 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
更新 2
我也在尝试不同的方法;看到这个问题 GHC compile DLL for use in VBA
我一直在为同样的问题而苦苦挣扎,但经过长时间的斗争,我设法 运行 来自 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
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();
}
3) 编译这些文件:
ghc -c Adder.hs
ghc -c StartEnd.c
4) 将以下文件从 "C:\Program Files\Haskell Platform.6.3\lib\include" 复制到您的构建文件夹(记得将 stg/Types.h 放入 stg 文件夹)。如果您愿意,您也可以复制 /include 文件夹中的所有内容:
HsFFI.h
ghcconfig.h
ghcautoconf.h
ghcplatform.h
stg/Types.h
5) 创建dll:
ghc -shared -o Adder.dll Adder.o Adder_stub.h StartEnd.o
6) 现在打开 Excel 并使用这个宏(在 Adder 之前先使用 HsStart)。记得link到你自己的文件夹:
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
7) 惊叹不已!