I’ve been doing a project with vulkan/sdl/ada for a few days so far. I have a few questions but this one will specifically be about the way I import the array from c, and my understanding of what the basic memory layout will look like inside. I am a new programmer so I may be completely in the incorrect weeds. I tried on my own for 2/3 days before posting this question.
Reasoning: The reason why I want to import the array into ada is because I want to do some checks/elaboration upon the contents of the array without just passing the System.Address and ignoring the rest.
What I am trying with the array:
- No copying.
- Follow correct convention.
- Be able to use it in ada without tons of conversion.
- The function that I am trying to pass it to is just a binding to vulkan that can take in a c array, so I could really just pass the Extension_Names_Address(System.Address) into the vulkan binding, but I just want to be sure that there are no weird pitfalls that I may be missing.
-- Ada, Get extension names from sdl.
Extension_Names_Count_Var : aliased SDL3_SDL_stdinc_h.Uint32;
Extension_Names_Address : System.Address :=
SDL3_SDL_vulkan_h.SDL_Vulkan_GetInstanceExtensions
(Extension_Names_Count_Var'Access);
Extension_Names_Var :
chars_ptr_array (size_t (1) .. size_t (Extension_Names_Count_Var))
with Import, Convention => C, Address => Extension_Names_Address; -- This is the unhappy line. I don't want to copy it, but I don't really know what this is doing, and reading more is confusing me.
-- Ada, The sdl binding for SDL_Vulkan_GetInstanceExtensions
-- Automatically generated by `gcc -c -fdump-ada-spec -C /filenames`
function SDL_Vulkan_GetInstanceExtensions
(count : access SDL3_SDL_stdinc_h.Uint32)
return System.Address -- /usr/include/SDL3/SDL_vulkan.h:200
with
Import => True,
Convention => C,
External_Name => "SDL_Vulkan_GetInstanceExtensions";
// C, The specification for SDL_Vulkan_GetInstanceExtensions.
extern SDL_DECLSPEC char const * const * SDLCALL SDL_Vulkan_GetInstanceExtensions(Uint32 *count);
-- The spec of the vulkan function with a simplified example of passing the array.
-- Over-simplified, but with the correct variable types, so this post isn't made an even longer code dump than it already is.
-- Ada, also an automatically generated c binding.
ppEnabledExtensionNames : System.Address;
// what this variable was in c.
const char* const* ppEnabledExtensionNames;
My secondary method: As seen above the const char* const* is the same in both the return type of the sdl function and intake for the simplified vulkan function, therefore, I could just take the System.Address of the first return and send it to the vulkan function. I have tried this and it seems to work correctly.
Third method: I suppose I could import the array into ada to do those extra checks and send the Extension_Names_Address just to go faster too. So using both might have benefits.
Expected basic memory layout for each of the three methods:
1: C array, Extension_Names_Address points to that array, Extension_Names_Var copies that array and now holds a correctly sized array in ada, vulkan would be taking in Extension_Names_Var and not the original c array with my code above.
2. C array, Extension_Names_Address points to that array, vulkan would take in Extension_Names_Address which points to the original c array.
3. Same as the above two methods, but vulkan would take method 2’s way of in-taking the array, and ada would hold its own copy of the array for me to do further work with. So vulkan would be pointing to the System.Address of the original c array, and I would have a copy in ada.
Summary of questions:
Is my current way with importing the array from the address okay?
Is my secondary method of sending the System.Address okay?
Is my third method of using both methods okay?
Is the expected memory layout I have good understanding?
How can I import the array using my existing first method without copying. Or maybe I have it correct already?
If you have any other opinions please send, I know this is a long post, but I think that I’m somewhat on the right track. I’ve been suffering for days, please understand that this is indeed a stupid first programming project, but I am stubborn. I dropped rust because I didn’t like how many times it used asterisks and other characters, and I’ve been happy with ada syntax so that’s a success so far. I have never really written ada or c before.