GnuCOBOL 调用 Rust:libcob:错误:找不到模块

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 源。

软件版本:

  • Ubuntu 22.04.1 LTS
  • cobc (GnuCOBOL) 3.1.2.0
  • 生锈 1.64.0

Jos*_*den 5

问题似乎是 COBOLcaller可执行文件试图动态加载指定的库,hello_rust.so而不是libcalled.so在运行时加载。

  • 无需修改任何内容的简单修复方法就是创建一个符号链接:

    $ ln -s libcalled.so hello_rust.so
    
    Run Code Online (Sandbox Code Playgroud)
  • 或者,添加-fstaticcobc命令中应在编译时静态链接 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)