D language function call with argument - sdl

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.

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);

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)

Related

Explaining C++ (C Binding Library) Function

I'm trying to understand a Function/Method in a Library in order to port it to Java however some parameters don't make any sense to me and reading the source code the library is based on is not helping.
Function (Note the API has few comments (We can also ignore the calc handle since it's got a supplier method))
Ssr calc_ssr(CalcHandle *calc, NoteInfo *rows, size_t num_rows, float music_rate, float score_goal) {
std::vector<NoteInfo> note_info(rows, rows + num_rows);
auto skillsets = MinaSDCalc(
note_info,
music_rate,
score_goal,
reinterpret_cast<Calc*>(calc)
);
return skillset_vector_to_ssr(skillsets);
}
NoteInfo Struct
struct NoteInfo
{
unsigned int notes;
float rowTime;
};
MinaSDCalc
// Function to generate SSR rating
auto
MinaSDCalc(const std::vector<NoteInfo>& NoteInfo,
const float musicrate,
const float goal,
Calc* calc) -> std::vector<float>
{
if (NoteInfo.size() <= 1) {
return dimples_the_all_zero_output;
}
calc->ssr = true;
calc->debugmode = false;
return calc->CalcMain(NoteInfo, musicrate, min(goal, ssr_goal_cap));
}
Calc expected input file data (Only care about the #Notes: ...)
Pastebin
Question
What is NoteInfo in calc_ssr, I don't know any C or C++ so the *rows to me just seems like a pointer to a Noteinfo instance, however the MinaSDCalc methods requires an Array/Vector which using a pointer to a single instance doesn't make sense to me (pairing this with the fact that NoteInfo needs another parameter rowTime which I think is time of Note occurrence in the file which means that value must not be constant otherwise the produced result would be inaccurate)
Github Project: https://github.com/kangalioo/minacalc-standalone (The code alone may not explain enough but it's worth a try; best to look at API.h and discern what's used from there. Though I do warn you a lot of the Code is esoteric)
Sorry if this doesn't make much sense but I've been looking into this since June/July and this API is the closest abstraction from the bare C++ code I could find.
NoteInfo * rows here is pass by pointer. So, rows actually is a pointer to an instance of type NoteInfo. This is one of the ways to pass arrays in c++ to a function. Since arrays are contiguous in memory so we can just increment the pointer by one and get the next element of the array.
for example look at these three ways to do exactly one thing, parameter to pass an array to a function :-
1. void myFunction(int *param) {}
2. void myFunction(int param[10]) {}
3. void myFunction(int param[]) {}
Look into this link for more understanding : https://www.tutorialspoint.com/cplusplus/cpp_passing_arrays_to_functions.htm
Also search for pass by pointer and pass by reference to look into different ways of passing arguments in c++.
2.however the MinaSDCalc methods requires an Array/Vector which using a pointer to a single instance doesn't make sense to me: as to this question of yours, you can now see MinaSDCalc is actually getting an array and not a single instance as passing the pointer is also one of the ways of passing an array in c++.

Unable to understand function-pointers in c++

I am reading The C++ Programming Language by Bjarne Stroustrup. It states an example to explain function-pointers:
int cmp1(const void∗ p, const void∗ q) // Compare name strings
{
return strcmp(static_cast<const User∗>(p)−>name,static_cast<const User∗>(q)−>name);
}
Then it uses this cmp1 in ssort, something like this:
int main()
{
cout << "Heads in alphabetical order:\n";
ssort(heads,6,sizeof(User),cmp1);
print_id(heads);
//Rest of function body
}
My question is: is &cmp1 being passed as an argument in ssort() because we can't pass a function as an argument, we can only pass a function-pointer?
My question is: is &cmp1 being passed as an argument in ssort() because we can't pass a function as an argument, we can only pass a function-pointer?
Your code does not use &cmp1. Hence, your question does not match your code.
Still, a function can be passed without using the addressof operator (&).
ssort(heads, 6, sizeof(User), &cmp1);
is the same as
ssort(heads, 6, sizeof(User), cmp1);
Functions decay to function pointers in this context.
A functions name indeed represent the starting address of the executable code for the function. So it's more like the arrays where its name can be used as pointer to the array itself. Also go through
https://www.geeksforgeeks.org/function-pointer-in-c/

How do declare an array in C++ as a parameter?

I am working with propriety code in my iOS project and all I have access to is the header files for my project. How do you declare an array in C++ so that it will return an array when I make a call?
Here's the header file method,
short WI_GetIDsFromList(int32_t module, int32_t *idsArray, uint32_t *count);
How do you declare an array to received an array of in32_t? I keep getting a parameter error for returnedIdsArray when I make this call? It works perfectly fine for count? I tried making it into a pointer but it did not work?
//Array of ID's
int32_t returnedIdsArray[] = {};
// Array of ID's count
uint32_t count;
rc += WI_GetIDsFromList(mod, returnedIdsArray, &count);
Another Example
short dpCount;
//Get number of data points from the device
WI_GetDatapointCount(modIDHDS, &dpCount);
//dpCount now has returned value of method WI_GetDatapointCount
NSLog#"%d", int(dpCount);
I think Mochi's question is how to declare the array that it suits the need of the function given in the header. If I understand him right, he has no influence to the function taking the array as parameter.
Did you try:
int32_t returnedIdsArray[MaximumExpectedIds];
Maybe there is also a function in the API giving you the number of Ids that you could use to determine the array size.
You cannot pass an array in C or C++, because they will always decay to a pointer to the first element.
You can, however, pass a reference to an array. It retains its array type rather than decay to a pointer, so sizeof() will return the actual size of the array rather than the sizeof pointer, and so on.
void f(char(&charArray)[30])
{
}
Syntax is pretty ugly though. A type alias can help:
using CharArray30 = char(&)[30];
void f(CharArray30 charArray)
{
}
etc. It has restrictions, though. For example, you cannot pass arrays of a different size.
If you need your function to work with various sizes, you can use a function template with a non-type parameter for the size:
template <size_t SIZE>
void f(int32_t module, int32_t(&idArray)[SIZE])
{
// ...
}
I guess that what you are trying to do is to have the function output a set of int values where the length is not known at compile-time.
In C++ an array has a fixed size that must be known at compile-time. The concept of "runtime-sized array" is called vector in C++.
Also, it is more natural to use the return value for values being returned. Your code could look like:
std::vector<int> WI_GetIDsFromList(int32_t mod);
and the calling code could be:
auto values = WI_GetIDsFromList(mod);

Matlab legacy_code Tool - Writing a wrapper functio to catch an array

currently I'm trying to use a C/C++ Code based Library in Matlab/Simulink by means of the Matlab legacy_code tool. I am very new to this, please have some patience with me.
I stumbled upon the problem, that I got class members which return an array.
What I did upon now is to follow the Matlab legacy-code examples, especially this one:
Integrate External C++ Object Methods
As far as I can see, the legacy_code tool demands a wrapper function to be wrapped around a method call, so basicaly I could, within this wrapper function manipulate the return value of the called methad any way necessary. This far no problem.
But, I'm not certain how to receive an array of information from the called method an then pass this array to Matlab/Simulink.
e.g. A method's return value is an pointer pointing at an array of information of which, let us assume, we know the length of valid information it holds.
/* Simple example */
uint8_t* BUS::answerRcvd()
{
static int r[10];
int i;
srand( (unsigned)time( NULL ) );
for ( i = 0; i < 10; ++i)
{
r[i] = rand();
}
return r;
}
Is there a way to create a wrapper function for such a method that would receive an array of information and pass it along to matlab?
Might there be a possibility to handle that array as e.g. single values of uint8_t (if way stay with the given example) and pass these like in an ordinary matlab function?
[a,b,c] = function()
I'm open to any suggestion, thank you very much in advance.
Ok, looks like I found a Solution to my problem.
As a wrapper function its possible to use the following pattern
void myfunc(double u1, double u2, double u3, double *y1, double *y2)
{
*y1=u1;
*y2=(u2+u3)/2;
}
This wrapper function the is then interfaced by the Legacy Code Tool (LCT) as followed:
def = legacy_code('initialize')
def.OutputFcnSpec = 'void myfunc(double u1, double u2, double u3, double y1[1], double y2[1])'
Simple as that. On C/C++ code use pointer nomenclature / syntax, on Matlab use array nomenclature / syntax.
I hope, this will help some people like me who need a solution to interface with legacy code which should not only accept multiple inputs, but multiple outputs as well.
In hindsight the option tuuse pointers is pretty obvious, but if you don't knoe how to teach your LCT how to interface with it, it easily becomes an tiring task.

How to call a JITed LLVM function with unknown type?

I am implementing a front-end for a JIT compiler using LLVM. I started by following the Kaleidoscope example in the LLVM tutorial. I know how to generate and JIT LLVM IR using the LLVM C++ API. I also know how to call the JITed function, using the "getPointerToFunction" method of llvm::ExecutionEngine.
getPointerToFunction returns a void* which I must then cast to the correct function type. For example, in my compiler I have unit test that looks like the following:
void* compiled_func = compiler.get_function("f");
auto f = reinterpret_cast<int32_t(*)(int32_t)>(compiled_func);
int32_t result = f(10);
The problem is that I have to know the function signature beforehand. In the example above, I have a function "f" which takes takes a 32-bit integer and returns a 32-bit integer. Since I create "f" myself, I know what the function type is, so I'm able to call the JIT'ed function. However, in general, I do not know what the function signature is (or what the struct types are) that are entered by the user. The user can create arbitrary functions, with arbitrary arguments and return types, so I don't know what function pointer type to cast the void* from LLVM's getPointerToFunction. My runtime needs to be able to call those functions (for a Read-Evaluate-Print loop, for example). How can I handle such arbitrary functions from my JIT runtime?
Thanks
There's not much information you get can from compiled_func - as you wrote, it's just a void*. But when you write "in general, I do not know what the function signature is", that's not accurate - you've just compiled that function, so you should have access to the LLVM Function object, which can be queried about its type. It's true that it's an LLVM IR type and not a C++ type, but you can often know which translates to which.
For example, if we borrow code from the tutorial's section on JITting Kaleidoscope:
if (Function *LF = F->Codegen()) {
LF->dump(); // Dump the function for exposition purposes.
// JIT the function, returning a function pointer.
void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
double (*FP)() = (double (*)())(intptr_t)FPtr;
fprintf(stderr, "Evaluated to %f\n", FP());
}
Then yes, FPtr was "assumed" to be of type double (), but there's also LF of type Function* here, so you could have done something like:
Type* RetTy = LF->getReturnType();
if (RetTy->isDoubleTy()) {
double (*FP)() = (double (*)())(intptr_t)FPtr;
fprintf(stderr, "Evaluated to %f\n", FP());
} else if (RetTy->isIntegerTy(32)) {
int (*FP)() = (int (*)())(intptr_t)FPtr;
fprintf(stderr, "Evaluated to %d\n", FP());
} else ...
And in much the same way, you can query a function about its parameter types.
A bit cumbersome? You can use your execution engine to invoke the function, via its handy runFunction method, which receives a vector of GenericValues and returns a GenericValue. You should still query the Function type to find what the underlying type under each GenericValue should be.