在 OS X 上从 Ocaml 通过 Ctypes 调用 Rmath

Call Rmath via Ctypes from Ocaml on OS X

我想使用 Ocaml libRmath 中提供的 R 数学函数。我通过 brew tap homebrew science && brew install --with-librmath-only r 成功安装了库。我最终在 /usr/local/lib 中得到一个 .dylib,在 /usr/local/include 中得到一个 .h。按照 Ocaml ctypes 教程,我在 utop

中执行此操作
#require "ctypes.foreign";;
open Ctypes;;
open Foreign;;
let test_pow = foreign "pow_di" (float @-> int @-> returning float);;

这抱怨找不到符号。我究竟做错了什么?需要先打开动态库吗?设置一些环境变量?谷歌搜索后,我也这样做了:

nm -gU /usr/local/lib/libRmath.dylib

它给出了一堆符号,所有符号都带有前导下划线,包括 00000000000013ff T _R_pow_di。在头文件中,pow_di 是通过来自 _R_pow_di 的一些 #define 指令定义的。我确实尝试了名称的变体,例如 "R_pow_di" 等

编辑:我尝试使用 Xcode 使用 Rmath 编译一个简单的 C 程序。手动设置包含路径包含/usr/local/include后,Xcode可以找到头文件Rmath.h。但是,在头文件中,包含 R_ext/Boolean.h 似乎不存在。此错误由 Xcode 标记并且编译停止。

菜鸟警报:这对 C 程序员来说可能是显而易见的...

为了使用外部库,您仍然需要link。至少有两种不同的方式,要么 link 使用编译器,要么 link 使用 dlopen.

甚至更动态

对于第一种方法,使用以下命令(作为初始近似值):

ocamlbuild -pkg ctypes.foreign -lflags -cclib,-lRmath yourapp.native 

在你的代码被放入yourapp.ml文件的前提下。

第二种方法是使用ctypes接口dlopen打开库。为 C 函数调用使用正确的类型和名称,如下所示:

let library = Dl.dlopen ~filename:"libRmath.dylib" ~flags:[]
let test_pow = foreign ~from:library "R_pow_di" (double @-> int @-> returning double)