我正在使用here中的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!()
}
使用结构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产生了兼容的接口?
[...]我期望的是0xdeadbeaf,然后是64位指针,然后是0xdeadbeaf,但是正如您所见,这不是我所得到的。
我们一定不能看到同一件事,因为我do看到了。
0x7ffcf5f4a5c8: 0xdeadbeaf 0x0 0x43fd9950 0x55ea
0x7ffcf5f4a5d8: 0xdeadbeaf 0x0 0x0 0x0
每个十六进制数字都是32位整数,因此您必须将其中两个取为64位整数。第一个是0x00000000deadbeaf,第二个是0x000055ea43fd9950(大概是register_natives
函数),第三个是0x00000000deadbeaf。 (从地址上也“很明显”:一个64位整数占用8个字节,因此需要两个来占用0x10字节。因此,每行有两个64位整数。)
程序出现段错误的原因可能是因为让外来代码引起恐慌的原因是undefined behavior。尝试将register_natives
功能更改为不会引起惊慌的内容。