例如,我的一个项目中有一个稍微复杂的库依赖情况:
/--------------------------------\
| |
/----> GRPC <------------------\ |
| | |
| (c++) | |
\------- A --------------> B |
| (rust) |
| |
\------------------> c++ <---/
Run Code Online (Sandbox Code Playgroud)
Rust 默认情况下更喜欢使用静态链接。可执行文件 A 还构建为静态链接 lib(std)c++。因此,据我了解,A 和 B 中都会有两个 STL 实现副本。这正是https://developer.android.com/ndk/guides/cpp-support#sr建议避免的模式。
但是,查看nm -DB 的动态链接表(例如通过 );我看不到导出的 lib(std)c++/grpc 符号。这是因为 Rust 默认将它们标记为隐藏。
我正在将代码移植到现代编译器,不幸的是,当从 Rust 调用 FFI 函数到 C++ 时遇到了一个微妙的分段错误。
堆栈跟踪显示,在过渡到 C++ 之后,Rust 提供的第一个参数神奇地消失了,这会误导 C++ 使用错误的参数。
代码有点私密,所以我不能在这里发布,但程序集显示了一些有趣的东西:
在 GCC-7(代码运行没有问题)中,汇编的前几行如下所示:
0x0000000000001119 <+0>: push rbp
0x000000000000111a <+1>: mov rbp,rsp
0x000000000000111d <+4>: push r13
0x000000000000111f <+6>: push r12
0x0000000000001121 <+8>: push rbx
0x0000000000001122 <+9>: sub rsp,0x128
0x0000000000001129 <+16>: mov QWORD PTR [rbp-0x118],rdi
0x0000000000001130 <+23>: mov rax,rsi
0x0000000000001133 <+26>: mov rsi,rdx
0x0000000000001136 <+29>: mov rdx,rsi
0x0000000000001139 <+32>: mov QWORD PTR [rbp-0x130],rax
0x0000000000001140 <+39>: mov QWORD PTR [rbp-0x128],rdx
0x0000000000001147 <+46>: mov QWORD PTR [rbp-0x120],rcx
0x000000000000114e <+53>: mov QWORD …Run Code Online (Sandbox Code Playgroud)