在 OCaml toploop 中使用 ctypes 加载和使用来自共享库的符号
Load and use symbols from shared library with ctypes in OCaml toploop
我正在尝试使用来自 OCaml 的小型独立 fortran 库中的函数。我可以用 gfortran -shared mvndst.f -o sharedlib
编译库。调用 nm sharedlib
显示符号列表,例如... T _mvndfn_
。
阅读 ctypes 教程示例后 https://github.com/ocamllabs/ocaml-ctypes/wiki/ctypes-tutorial 我尝试做类似 let mvndfn = foreign "mvndfn" (ptr double @-> returning float)
的事情。找不到该符号。也许并不奇怪,因为我没有告诉它在哪里看 - 但我不知道如何看。
这完全可以吗?如何告诉 toploop 寻找这个共享库? Fortran 不是 C 有关系吗?如果程序在 toploop 中运行,我如何最终编译和 link 程序?
(这是在 OS X 上)
Foreign.foreign
接受一个可选参数 ?from
,它是一个 Dl.library
类型的值(你可以看到它 in the docs)。您可以获得其中一个 Dl.dlopen
(动态加载是一个复杂的主题,但您通常需要 [RTLD_LAZY]
)。
这是一个使用 libpng
的例子:
# let libpng = Dl.dlopen ~flags:[Dl.RTLD_LAZY] ~filename:"/usr/lib/x86_64-linux-gnu/libpng16.so.16";;
val libpng : Dl.library = <abstr>
# open Foreign;;
# open Ctypes_static;;
# let f = foreign ~from:libpng "png_get_libpng_ver" (ptr void @-> returning (ptr char));;
val f : unit Ctypes_static.ptr -> char Ctypes_static.ptr = <fun>
# let p = f Ctypes.null;;
val p : char Ctypes_static.ptr = (char*) 0x7f9d5220e64e
# Ctypes.string_from_ptr ~length:6 p;;
- : string = "1.6.26"
我正在尝试使用来自 OCaml 的小型独立 fortran 库中的函数。我可以用 gfortran -shared mvndst.f -o sharedlib
编译库。调用 nm sharedlib
显示符号列表,例如... T _mvndfn_
。
阅读 ctypes 教程示例后 https://github.com/ocamllabs/ocaml-ctypes/wiki/ctypes-tutorial 我尝试做类似 let mvndfn = foreign "mvndfn" (ptr double @-> returning float)
的事情。找不到该符号。也许并不奇怪,因为我没有告诉它在哪里看 - 但我不知道如何看。
这完全可以吗?如何告诉 toploop 寻找这个共享库? Fortran 不是 C 有关系吗?如果程序在 toploop 中运行,我如何最终编译和 link 程序?
(这是在 OS X 上)
Foreign.foreign
接受一个可选参数 ?from
,它是一个 Dl.library
类型的值(你可以看到它 in the docs)。您可以获得其中一个 Dl.dlopen
(动态加载是一个复杂的主题,但您通常需要 [RTLD_LAZY]
)。
这是一个使用 libpng
的例子:
# let libpng = Dl.dlopen ~flags:[Dl.RTLD_LAZY] ~filename:"/usr/lib/x86_64-linux-gnu/libpng16.so.16";;
val libpng : Dl.library = <abstr>
# open Foreign;;
# open Ctypes_static;;
# let f = foreign ~from:libpng "png_get_libpng_ver" (ptr void @-> returning (ptr char));;
val f : unit Ctypes_static.ptr -> char Ctypes_static.ptr = <fun>
# let p = f Ctypes.null;;
val p : char Ctypes_static.ptr = (char*) 0x7f9d5220e64e
# Ctypes.string_from_ptr ~length:6 p;;
- : string = "1.6.26"