在一个结构中,c,struct,rust,java-native-interface,unsafe"/>

首页 > 解决方案 > 带有选项的奇怪内存布局在一个结构中

问题描述

我正在使用这里的 JNI 定义。我创建了一个 JNINativeInterface_,其中大多数成员初始化为 None。然后我运行使用RegisterNatives上述结构的字段的本机代码。我这样初始化RegisterNatives和周围的字段:

SetDoubleArrayRegion: unsafe { transmute(0xdeadbeaf as u64) },
RegisterNatives: Some(register_natives),
UnregisterNatives: unsafe { transmute(0xdeadbeaf as u64) },

register_natives像这样定义(这与库类型完全匹配):

unsafe extern "system" fn register_natives(env: *mut sys::JNIEnv,
                                           clazz: jclass,
                                           methods: *const JNINativeMethod,
                                           nMethods: jint) -> jint {
    unimplemented!()
}

使用 struct segfaults 的本机代码(并且似乎得到一个空 ptr 而不是register_natives)。

结构的相关部分在 GDB 下如下所示:

0x7ffcf5f4a5b8: 0x0 0x0 0x0 0x0
0x7ffcf5f4a5c8: 0xdeadbeaf  0x0 0x43fd9950  0x55ea
0x7ffcf5f4a5d8: 0xdeadbeaf  0x0 0x0 0x0
0x7ffcf5f4a5e8: 0x0 0x0 0x0 0x0

我对我正在看的东西感到困惑,因为我期待 0xdeadbeaf ,然后是 64 位指针,然后是 0xdeadbeaf,但正如你所看到的,这不是我得到的。我对如何在幕后表示选项的假设有误吗?为什么 bindgen/上述库似乎 Option 会导致兼容的接口?

标签: cstructrustjava-native-interfaceunsafe

解决方案


[...] 我期待 0xdeadbeaf,然后是 64 位指针,然后是 0xdeadbeaf,但正如你所看到的,这不是我得到的。

我们不能看到同样的事情,因为我确实看到了。

0x7ffcf5f4a5c8: 0xdeadbeaf  0x0 0x43fd9950  0x55ea
0x7ffcf5f4a5d8: 0xdeadbeaf  0x0 0x0 0x0

每个十六进制数都是一个 32 位整数,所以你必须取其中两个来组成一个 64 位整数。第一个是 0x00000000deadbeaf,第二个是 0x000055ea43fd9950(你的register_natives函数,大概),第三个是 0x00000000deadbeaf。(从地址上也“显而易见”:一个 64 位整数占用 8 个字节,因此占用 0x10 个字节需要两个。因此,每行有两个 64 位整数。)

程序段错误的原因可能是因为通过外部代码让恐慌解除是未定义的行为。尝试将您的register_natives功能更改为不会惊慌的东西。


推荐阅读