Since Spotify is unlikely to provide a successor to libspotify anytime soon, I'm trying to wrap it into a thin Rust library that I can use for other projects. I'm using Bindings generated from the header file by rust-bindgen. Since they are quite long (~1100 lines) and not that easy to shrink down to only the important bits, I created a pastebin containing the code.
Calling sp_build_id works just fine, invoking sp_session_create on the other hand, causes a segfault at address 0x000001C0
. Searching for libspotify and that memory address yielded this post. It suggests that something is wrong with the string marshalling, I just cannot figure out what it could be or if it indeed is the string marshalling.
This is how I call the method:
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
points to a folder in my PC in which libspotify can store its assets and SP_APP_KEY_PATH
points to the binary file with the application key. This all works fine (I have checked the generated code after the macros).
sp_session_create
looks like this:
#[link(name = "libspotify")]
extern "system" {
pub fn sp_session_create(config: *const sp_session_config, sess: *mut *mut sp_session) -> sp_error;
}
The system
-callconv expands to stdcall
on 32-bit and cdecl
on 64-bit, so it should just work for libspotify.
I'm running Windows 10, Rust nightly 1.10 32-bit MSVC and I'm using libspotify 12.1.51. I currently do not have a Linux machine at my disposal, so it's kinda hard to test the code on other operating systems. I'd be glad if somebody else could try to test out the code and see if it works for them or not. I'd also gladly appreciate any ideas on how I might improve the FFI code.