从Rust FFI调用sp_session_create段错误

时间:2016-05-09 19:15:54

标签: segmentation-fault rust ffi libspotify

由于Spotify不太可能很快提供libspotify的继任者,我试图将其包装到一个瘦的Rust库中,我可以将其用于其他项目。我正在使用由rust-bindgen从头文件生成的Bindings。由于它们很长(~1100行)并且不容易缩小到只有重要位,所以我创建了一个包含代码的pastebin

调用sp_build_id工作正常,另一方面调用sp_session_create会导致地址0x000001C0发生段错误。搜索libspotify并且该内存地址产生this post。它表明字符串编组有问题,我只是无法弄清楚它是什么,或者它确实是字符串编组。

这就是我调用方法的方法:

fn main() {
    let app_key = include_bytes!(env!("SP_APP_KEY_PATH"));
    let cache_path = ::std::ffi::CString::new(env!("SP_CACHE_PATH")).unwrap();

    let config = sp_session_config {
        api_version: 12,
        cache_location: cache_path.as_ptr(),
        settings_location: cache_path.as_ptr(),
        application_key: &app_key[..] as *const _ as *const ::std::os::raw::c_void,
        application_key_size: app_key.len() as u64,
        ..Default::default()
    };

    let mut ptr = ::std::ptr::null_mut();
    match unsafe { sp_session_create(&config, &mut ptr) } {
        Enum_sp_error::SP_ERROR_OK => println!("Session creation succeeded!"),
        err => println!("Session creation failed! {:?}", err)
    }
}

SP_CACHE_PATH指向我的PC中的文件夹,其中libspotify可以存储其资产,SP_APP_KEY_PATH指向具有应用程序密钥的二进制文件。这一切都很好(我在宏之后检查了生成的代码)。

sp_session_create看起来像这样:

#[link(name = "libspotify")]
extern "system" {
    pub fn sp_session_create(config: *const sp_session_config, sess: *mut *mut sp_session) -> sp_error;
}

system - callconv在32位上扩展为stdcall,在64位上扩展为cdecl,因此它应该适用于libspotify。

我正在运行Windows 10,Rust夜间1.10 32位MSVC,我正在使用libspotify 12.1.51。我目前没有Linux机器,所以在其他操作系统上测试代码有点困难。如果其他人可以尝试测试代码并查看它是否适用于我们,我会很高兴。我也很高兴地了解如何改进FFI代码。

0 个答案:

没有答案