我想从GnuCOBOL给Rust打电话.作为测试,我从Brian Tiffin的GNUCobol FAQ中复制了Can GnuCOBOL interface with Rust?中第一个示例中的代码,但在运行它时遇到错误.

预期:

$ make -B
rustc --crate-type=dylib called.rs
LD_RUN_PATH=. cobc -xj caller.cob -L. -lcalled
:Hello, world:

实际:

$ 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

在从命令行编译这两个文件,然后使用$ ./caller之后,我得到了相同的错误.

根据cobc手册页以及GnuCOBOL manualRust reference的链接部分,语法似乎是正确的.我已经try 了GnuCOBOL手册中描述的$ ./caller COB_LIBRARY_PATH=.,但没有什么不同.Rust源代码如预期的那样编译为库,但COBOL没有找到它.

使用$ cobcrun caller代替显示libcob: error: module 'caller' not found.

关于类似错误的This个问题是关于静态链接多个COBOL源文件的,这工作得很好,而关于类似错误的this个问题似乎是关于X"AF"的问题,这里不使用它.静态地将C源代码与Jay Moseley的C Wrapper for Calling Library Function示例链接在一起可以达到预期效果.不支持静态链接 rust 源.

软件版本:

  • Ubuntu 22.04.1 LTS
  • COBC(GnuCOBOL)3.1.2.0
  • Rustc 1.64.0

推荐答案

问题似乎是COBOL caller可执行文件试图在运行时动态加载名为hello_rust.so而不是libcalled.so的库.

  • 无需修改任何内容的简单解决方案是只需创建一个symlink:

    $ ln -s libcalled.so hello_rust.so
    
  • 或者,将-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
    

作为参考,我们可以通过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

Rust相关问答推荐

什么是谓词的简短和简洁类型

空字符串转换为Box字符串时是否分配?<>

如何在Bevy/Rapier3D中获得碰撞机的计算质量?

使用Clap时如何将String作为Into Str参数传递?

无法理解铁 rust &S错误处理

从Type::new()调用函数

如何高效地将 struct 向量中的字段收集到单独的数组中

将特征与具有生命周期的关联类型一起使用时的生命周期方差问题

一次不能多次borrow *obj作为可变对象

Rust 如何返回大类型(优化前)?

Google chrome 和 Apple M1 中的计算着色器

当锁被释放时,将锁包装到作用域中是否会发生变化?

缺失serde的字段无法设置为默认值

Rust:`sort_by` 多个条件,冗长的模式匹配

为什么 for_each 在释放模式(cargo run -r)下比 for 循环快得多?

使用 serde_json 进一步处理字段

具有生命周期和以后引用的可变方法

使用 `.` 将 T 转换为 &mut T?

如何构建包含本地依赖项的 docker 镜像?

如何在 Rust 中构建一个 str