3

I am learning D and have mostly experience in C#. Specifically I am trying to use the Derelict3 Binding to SDL2. I have been able to get some basic functionality working just fine but I have become stumped on how to create an array argument for a specific call.

The library contains a call

SDL_RenderDrawLines(SDL_Renderer*, const(SDL_Point)*, int)  //Derelict3 Binding

And I have been unable to correctly form the argument for

const(SDL_Point)*

The SDL Documentation for this function states that this argument is an array of SDL_Point, but I am unclear how to create an appropriate array to pass to this function.

Here is an example of what I have at the moment:

void DrawShape(SDL_Renderer* renderer)
{
    SDL_Point a = { x:10, y:10};
    SDL_Point b = { x:500, y:500};

    const(SDL_Point[2]) points = [a,b];

    Uint8 q = 255;
    SDL_SetRenderDrawColor(renderer,q,q,q,q);
    SDL_RenderDrawLines(renderer,points,1);
}

And the compiler complains that I am not passing the correct type of argument for const(SDL_Point)* in points.

Error: function pointer SDL_RenderDrawLines (SDL_Renderer*, const(SDL_Point)*, int)
is not callable using argument types (SDL_Renderer*, const(SDL_Point[2u]), int)

I suspect this is a fundamental misunderstanding on my part so any help would be appreciated.

Martin G
  • 17,357
  • 9
  • 82
  • 98
MrJolo
  • 33
  • 4

2 Answers2

5

Arrays aren't implicitly castable to pointers in D. Instead, each array (both static and dynamic) has an intrinsic .ptr property that is a pointer to its first element.

Change your code to:

SDL_RenderDrawLines(renderer,points.ptr,1);
Vladimir Panteleev
  • 24,651
  • 6
  • 70
  • 114
  • chances are that the int argument is the length of the array so the call will be `SDL_RenderDrawLines(renderer, points.ptr, points.size);` – ratchet freak Aug 13 '13 at 09:49
  • Originally I had something along those lines but through my various permutations at attempting to get this to work originally I took that out due to one of my attempts not supporting `.length` but I will put something like that back in, Thanks! – MrJolo Aug 13 '13 at 15:20
1

given that the call asks for a pointer and length, I feel it is safer to define you own wrapper:

SDL_RenderDrawLines(SDL_Renderer* rend, const SDL_Point[] points){
    SDL_RenderDrawLines(rend,points.ptr,points.length);
}

(why it isn't defined I don't know, any performance hit from the extra function call is just a -inline away from being resolved)

ratchet freak
  • 47,288
  • 5
  • 68
  • 106
  • Pardon my inexperience but I am unfamiliar with how to inline the function. I take it that you just pass an `-inline` argument to the compiler and it determines when to inline? I found the following at [D Lang: Functions](http://dlang.org/function.html) Inline Functions There is no inline keyword. The compiler makes the decision whether to inline a function or not, analogously to the register keyword no longer being relevant to a compiler's decisions on enregistering variables. (There is no register keyword either.) – MrJolo Aug 13 '13 at 15:23
  • yeah `-inline` is a compiler argument that allows the compiler to inline some functions, this is disabled by default in debug builds for clarity in the debugger – ratchet freak Aug 13 '13 at 15:25
  • This will not work as-is. Functions in the current module and imported modules are not part of the same overload set. The callee must be fully-qualified, or the function name should be different. For the purpose of wrapping C libraries with prefixed identifiers, it is customary to use namespaces, or lacking those in OOP-capable languages, a type (eg. "SDL" struct) and static methods, so the call becomes SDL.RenderDrawLines. – Vladimir Panteleev Aug 13 '13 at 16:13
  • "why it isn't defined I don't know" - because once you start going down this route, for consistency you'll also want to take care of arrays in structures, and in structures returned by functions, and it becomes a slippery slope towards some kind of complete marshaling behemoth. – Vladimir Panteleev Aug 13 '13 at 16:14