Search code examples
spotifylibspotify

What compiler flags does libspotify expect related to packing?


I'm using libspotify 12.1.51 on Windows. While it mostly works as expected, I'm having some difficulty with sp_offline_sync_status:

typedef struct sp_offline_sync_status {
  int queued_tracks;
  sp_uint64 queued_bytes;

  int done_tracks;
  sp_uint64 done_bytes;

  int copied_tracks;
  sp_uint64 copied_bytes;

  int willnotcopy_tracks;

  int error_tracks;
  bool syncing;

} sp_offline_sync_status;

(sp_uint64 is a typedef for an unsigned __int64 on Windows and uint64_t otherwise. When building in C (not C++) and if bool is not otherwise defined, it is a typedef for unsigned char.)

When I call sp_offline_sync_get_status, only queued_tracks seems to have correct data, the rest is garbage. However, if I edit the header file to include #pragma pack(1), it seems to give more plausible results. I observe this behaviour even when I try to build the spshell example that comes with libspotify.*

This leads me to believe that the libspotify binary is compiled with some different compiler flags from the defaults, at least on Windows with Visual C++. How should I be compiling C or C++ code to use libspotify? Or should I use #pragma pack before #including api.h and then restore it back? Can I expect this to remain stable in future versions of libspotify or is it likely to change? How does it vary across platforms?

My true goal is to write C# P/Invoke code, that works on a variety of platforms using Mono. On non-Windows platforms does libspotify stick to the default alignment for the native compiler, or will I need to specify custom alignment on each platform?

[*] - I did have to fix some other bugs first, though. As provided in libspotify 12.1.51, on Windows spshell registers control key-presses (e.g. shift, ctrl) as typing a NUL character. This prevents typing or pasting spotify URIs into the console. This can be fixed by editing spshell_win32.c to add case 0: break; to the switch statement in console_input. Also, it uses the string format specifier "%zd" in spshell.c in the function offline_status_updated. The Microsoft C runtime doesn't seem to handle this, so it needs to be changed (e.g. to "%Iu" if you only want it to work on Windows, or to a platform-sensitive macro).


Solution

  • libspotify is compiled with '-Zp4' whereas standard appears to be '-Zp8'. I guess one could either compile with that flag, or use the #pragma pack(4) directive (I actually think 4 is more correct than 1, as you used in your question)

    Will put a note in Jira to fix the errors in spshell.c you pointed out. Thanks!