sdlada
sdlada copied to clipboard
Logging functions fail on Windows
SDL.Log.Put ("foo");
SDL.Log.Put_Debug ("bar");
...outputs the following for me on Win 7 64-bit:
INFO: foo
DEBUG:
The "bar" is missing. Gdb reveals the string is not being passed from Ada to C properly in the call to SDL_LogDebug(). I suspect it's related to this caveat on 'C' calling conventions, especially because SDL_Log() takes one argument while SDL_LogDebug() takes two:
In C, varargs allows a function to take a variable number of arguments. There is no direct equivalent in this to Ada. One approach that can be used is to create a C wrapper for each different profile and then interface to this C wrapper. For example, to print an int value using printf, create a C function printfi that takes two arguments, a pointer to a string and an int, and calls printf. Then in the Ada program, use pragma Import to interface to printfi.
It may work on some platforms to directly interface to a varargs function by providing a specific Ada profile for a particular call. However, this does not work on all platforms, since there is no guarantee that the calling sequence for a two argument normal C function is the same as for calling a varargs C function with the same two arguments.
Yes, I did come across this in development, not sure how to get it to work, tbh. Any ideas welcome.
As per SDL wiki, SDL_LogDebug takes a format string as first argument:
void SDL_LogDebug(int category, const char* fmt, ...)
Thus,
procedure SDL_Log (Category : in Categories; Message : in C.char_array) with Import => True, Convention => C, External_Name => "SDL_LogDebug";
has the wrong interface, it should be
SDL_Log (Category : in Categories; Fmt : in C.char_array; Message : in C.char_array) ...
and then be called like
SDL_Log (Category, C.To_C ("%s"), C.To_C (Message));
Similiar for other SDL_Log functions.
Fixes with commit b75a8aeb357ee3f10160575ae8cfd9dc504223f1.