由于awesome guide by Jonathan Protzenko,我设法在Windows(在Cygwin中)安装并运行 OCaml + OPAM + utop 。在 utop 中,我特别希望能够使用 ctypes + ctypes.foreign 快速实验和原型访问各种WinAPI调用。从理论上讲,我成功安装了 ctypes 包(opam install ...
成功)。不幸的是,当我尝试在utop中实际加载 时,他们失败了 ,并出现了一条令人惊讶的错误消息:
utop # #require "ctypes.foreign";;
Error: Reference to undefined global `Ctypes_closure_properties'
尝试在rlwrap ocaml
中执行相同操作会产生更长的错误消息:
# #require "ctypes.foreign";;
C:\OCaml\lib\unix.cma: loaded
C:\OCaml\lib\bigarray.cma: loaded
C:\OCaml\lib\str.cma: loaded
C:\cygwin64\home\Mateusz\.opam\system\lib\bytes: added to search path
C:\cygwin64\home\Mateusz\.opam\system\lib\ctypes: added to search path
C:\cygwin64\home\Mateusz\.opam\system\lib\ctypes\ctypes.cma: loaded
C:\cygwin64\home\Mateusz\.opam\system\lib\ctypes\ctypes-foreign-base.cma: loaded
Cannot load required shared library dllctypes-foreign-base_stubs.
Reason: dllctypes-foreign-base_stubs.dll: Cannot resolve ffi_type_pointer.
C:\cygwin64\home\Mateusz\.opam\system\lib\ctypes\ctypes-foreign-unthreaded.cma: loaded
Characters -1--1:
#require "ctypes.foreign";;
Error: Reference to undefined global `Ctypes_closure_properties'
注意:full transcript of the sessions is here - 它包含cmd.exe终端中utop
会话的输出,以及Cygwin终端中的其他rlwrap ocaml
会话的输出。
我完全不知道为什么会这样,或者我如何进一步尝试调试/查明/诊断情况,以便我可以尝试找到一些解决方法。 (顺便说一下 - 虽然我在C / C ++和Linux方面经验丰富,但我和OCAMl& OPAM都是新手。)以下是我所拥有的一些问题,我希望可能有所帮助轻推问题足以让我解决障碍:
-fpic
?]相关联的答案,但它们看起来都非常hackish,我尝试的那些似乎都没有用,至少在我的情况下。答案 0 :(得分:1)
mingw64-x86_64-libffi附带静态和动态库,但gnu链接器默认使用动态版本。
修补ctypes的构建将非常烦人(ctypes的构建系统相当复杂,脚本和makefile的混合)。因此,请尝试以下操作:删除动态库(/usr/x86_64-w64-mingw32/sys-root/mingw/lib/libffi.dll.a
和/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libffi-6.dll
),重建ctypes,然后恢复已删除的文件。
顺便说一下:https://fdopen.github.io/opam-repository-mingw/installation/包含一个补丁版本的flexdll(https://github.com/alainfrisch/flexdll/pull/3已应用 - 问题不是特定于libffi),它支持libffi的动态和静态版本。如果您的路径中有opam install ctypes-foreign ctypes utop
,则/usr/x86_64-w64-mingw32/sys-root/mingw/bin
应该开箱即用。下面的完整分步指南:
cygwin-install gui
以启动 Cygwin设置/安装程序并使用它来安装一些文本编辑器( joe 或 nano 或 vim 或您喜欢的任何内容。使用您安装的文本编辑器编辑~/.bashrc
文件,添加以下行:
export PATH="/usr/x86_64-w64-mingw32/sys-root/mingw/bin:$PATH"
然后在 Cygwin终端中执行它(只需在终端中键入它,或者运行以下命令):
$ source ~/.bashrc
安装 depext ,它将自动下载OPAM包所需的任何操作系统级别(本机)依赖项,使用它来安装 ctypes 和 utop :
$ opam install depext depext-cygwinports
$ opam depext -i ctypes-foreign ctypes utop
从 Cygwin终端切换到 cmd.exe ,,例如在 Cygwin Terminal <中键入以下命令/ EM>:
$ cmd /c start cmd
在 cmd.exe 终端中启动 utop ,然后使用它来调用MessageBox WinAPI function作为测试,确保所有人都能正常运行:
c:> utop
utop # #require "ctypes.foreign";;
utop # let dll = Dl.dlopen ~filename:"user32.dll" ~flags:[];;
val dll : Dl.library = <abstr>
utop # open Ctypes;;
utop # let mb =
Foreign.foreign ~from:dll "MessageBoxA"
(ptr void @-> string @-> string @-> uint @-> returning int) ;;
val mb : unit Ctypes_static.ptr -> bytes -> bytes -> Unsigned.uint -> int =
<fun>
utop # mb null "hello" "world" Unsigned.UInt.zero;;
- : int = 1
utop # #quit;;
c:>
[注意:并非所有上述 utop 命令都是必需的,但这对我有用。]