我正在Haskell中构建一个可在macOS和Windows上使用的DLL,并且后者有问题。具体来说,DLL中的符号数变得太大(“导出序数太大”):
Linking mydll.dll ...
C://Users//bjorn//AppData//Local//Programs//stack//i386-windows//ghc-8.6.5//mingw//bin/ld.exe: Error: export ordinal too large: 73799
collect2.exe: error: ld returned 1 exit status
`gcc.exe' failed in phase `Linker'. (Exit code: 1)
Run Code Online (Sandbox Code Playgroud)
这与https://gitlab.haskell.org/ghc/ghc/wikis/windows-dynamic-linking中描述的问题密切相关,该问题描述了我遇到的序数限制:
这样做的主要原因是
PE规范中的限制,该规范将ordinal值(与导出符号关联的唯一数字/索引)使用16位int。这限制了我们可以导出到2^16-1 (~65k)符号的符号数量。
不幸的是,我缺乏@Phyx的专业知识,对于如何解决/解决我的案例问题有些困惑。
通过一些试验,我使用attoparsec替换了一些代码,据undefined我所知,该代码阻止了attoparsec(以及它的某些依赖项)被链接。这使符号的数量减少到60232(使用计数nm -g mydll.dll | wc -l)。这并不是说attoparsec是问题所在,而只是提供DLL如何随着依赖关系增长的示例。
DLL的最终用户API由许多FFI foreign export ccall函数组成。作为一个例子,有功能/动作logStarted(foreign export ccall logStarted :: IO ())。Grepping用于logStarted在输出nm -g我发现:
6b6910d0 D _FFI_logStarted_closure
6af817fc T _FFI_logStarted_info
6b6910d8 D _FFI_zdfstableZZC0ZZCmainZZCFFIZZClogStarted_closure …Run Code Online (Sandbox Code Playgroud)