Jos*_*h E 3 cobol gnucobol rust
我想从 GnuCOBOL 调用 Rust。我已经复制了Can GnuCOBOL interface with Rust?中第一个示例的代码。来自 Brian Tiffin 的 GNUCobol FAQ 作为测试,但在运行时出现错误。
预期的:
$ make -B
rustc --crate-type=dylib called.rs
LD_RUN_PATH=. cobc -xj caller.cob -L. -lcalled
:Hello, world:
Run Code Online (Sandbox Code Playgroud)
实际的:
$ make -B
rustc --crate-type=dylib called.rs
LD_RUN_PATH=. cobc -xj caller.cob -L. -lcalled
libcob: error: module 'hello_rust' not found
make: *** [makefile:5: caller] Error 1
Run Code Online (Sandbox Code Playgroud)
从命令行编译这两个文件然后使用$ ./caller.
根据手册页以及GnuCOBOL 手册和Rust 参考cobc的链接部分,语法似乎是正确的。我已经按照 GnuCOBOL 手册中的描述进行了尝试,但没有什么区别。Rust 源代码按预期编译为库,但 COBOL 找不到它。$ ./caller COB_LIBRARY_PATH=.
使用$ cobcrun caller代替显示libcob: error: module 'caller' not found.
这个关于类似错误的问题是关于静态链接多个COBOL源文件,它工作得很好,而这个关于类似错误的问题似乎是 的问题X"AF",这里没有使用它。将 C 源代码静态链接到 Jay Moseley 的用于调用库函数的 C 包装器示例可以按预期工作。不支持静态链接 Rust 源。
软件版本:
问题似乎是 COBOLcaller可执行文件试图动态加载指定的库,hello_rust.so而不是libcalled.so在运行时加载。
无需修改任何内容的简单修复方法就是创建一个符号链接:
$ ln -s libcalled.so hello_rust.so
Run Code Online (Sandbox Code Playgroud)
或者,添加-fstatic到cobc命令中应在编译时静态链接 Rust 库,从而消除动态库运行时调用。
该示例Makefile可以更新为如下所示:
# GnuCOBOL and Rust
.RECIPEPREFIX = >
caller: caller.cob libcalled.so
> LD_RUN_PATH=. cobc -fstatic -xj caller.cob -L. -lcalled
libcalled.so: called.rs
> rustc --crate-type=dylib called.rs
Run Code Online (Sandbox Code Playgroud)
作为参考,我们可以通过 strace 调查可执行文件正在做什么,以查看 COBOL 运行时正在执行哪些系统调用 - 在我们的例子中 - 它无法找到哪些文件。
$ strace ./caller 2>&1 | grep hello_rust
access("./hello_rust.so", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib64/gnucobol/hello_rust.so", R_OK) = -1 ENOENT (No such file or directory)
write(2, "module 'hello_rust' not found", 29module 'hello_rust' not found) = 29
Run Code Online (Sandbox Code Playgroud)