为何Rust编译的ABI库可调用未在源码中定义的printf函数?
为什么能调用Rust库中未定义的printf函数?
我编写了一个简单的Rust文件,代码如下:
#[no_mangle] pub extern "C" fn add(a: i32, b: i32) -> i32 { a + b }
随后尝试在Java中调用该库,通过JNA定义了如下包含两个Native方法的接口:
public interface CLibrary extends Library { CLibrary INSTANCE = Native.load("add", CLibrary.class); void printf(String format, Object... args); int add(int a, int b); }
注意其中我额外定义了printf方法,该方法并未在Rust源码中实现,但调用以下代码时却成功执行:
CLibrary.INSTANCE.printf("Hello, World!\n"); System.out.println(CLibrary.INSTANCE.add(1, 2));
输出结果为:
3 Hello, World!
请问为何我能调用未在Rust源码中定义的printf函数?
解答
这是动态链接机制的标准行为:
- 当你用JNA加载自己编译的Rust动态库时,系统的动态链接器会负责解析所有未在你的库中找到的符号。
printf是C标准库的核心函数,而Rust默认编译动态库时会自动链接系统的C标准库(比如Linux下的libc.so、Windows下的msvcrt.dll)。 - 动态链接器在你的Rust库中找不到
printf的符号时,会自动去已加载的依赖库(包括系统标准C库)中查找对应的实现,所以最终调用的是系统C库提供的printf函数,而非你自己实现的版本。
简单说,你的Rust库本身就依赖了系统C库,动态链接器帮你“补全”了这个未定义的函数实现。
内容的提问来源于stack exchange,提问作者Sheldon Wei
相关产品推荐
相关产品推荐

