Thread overview | ||||||
---|---|---|---|---|---|---|
|
October 10, 2017 How to call function with variable arguments at runtime? | ||||
---|---|---|---|---|
| ||||
I need to store a hetrogeneous array of delegates. How can I do this but still call the function with the appropriate number of parameters at run time? I have the parameters as Variant[] params and a function/delegate pointer(void* for now). Normally I'd push the parameters on the stack and use a call, but I'm sure D has some ability to do this, like apply(foo, args) would be the same as foo(args[0], ..., args[1]). I'm not concerned about type correctness, it should always be consistent between what I call and what is stored. Thanks. |
October 10, 2017 Re: How to call function with variable arguments at runtime? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mr. Jonse | On Tuesday, 10 October 2017 at 02:58:45 UTC, Mr. Jonse wrote: > I need to store a hetrogeneous array of delegates. How can I do this but still call the function with the appropriate number of parameters at run time? > > I have the parameters as Variant[] params and a function/delegate pointer(void* for now). > > Normally I'd push the parameters on the stack and use a call, but I'm sure D has some ability to do this, like apply(foo, args) would be the same as foo(args[0], ..., args[1]). > > I'm not concerned about type correctness, it should always be consistent between what I call and what is stored. > > Thanks. Not entirely sure what you're wanting to do, but sounds a lot like variadic parameters. https://dlang.org/spec/function.html#variadic mixed with some compile-time terminology. |
October 10, 2017 Re: How to call function with variable arguments at runtime? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mr. Jonse | On Tuesday, 10 October 2017 at 02:58:45 UTC, Mr. Jonse wrote:
> I need to store a hetrogeneous array of delegates. How can I do this but still call the function with the appropriate number of parameters at run time?
>
> I have the parameters as Variant[] params and a function/delegate pointer(void* for now).
>
> Normally I'd push the parameters on the stack and use a call, but I'm sure D has some ability to do this, like apply(foo, args) would be the same as foo(args[0], ..., args[1]).
>
> I'm not concerned about type correctness, it should always be consistent between what I call and what is stored.
>
> Thanks.
Like so?
import std.variant;
void foo(int a, string b, float c) {
import std.stdio;
writefln("a = %s, b = %s, c = %s", a, b, c);
}
auto apply(alias fn)(Variant[] values) {
import std.traits : ParameterTypeTuple;
import std.conv : emplace;
alias Types = ParameterTypeTuple!fn;
assert(values.length == Types.length);
Types args = void;
foreach(i, ref arg; args) {
// using emplace instead of assignment here to be fully correct
emplace!(typeof(arg))(&arg, values[i].get!(typeof(arg)));
}
return fn(args);
}
void main() {
Variant[] values = [Variant(1), Variant("Hello world"), Variant(3.14159f)];
apply!foo(values);
}
|
October 11, 2017 Re: How to call function with variable arguments at runtime? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | On Tuesday, 10 October 2017 at 08:26:37 UTC, Marc Schütz wrote:
> On Tuesday, 10 October 2017 at 02:58:45 UTC, Mr. Jonse wrote:
>> I need to store a hetrogeneous array of delegates. How can I do this but still call the function with the appropriate number of parameters at run time?
>>
>> I have the parameters as Variant[] params and a function/delegate pointer(void* for now).
>>
>> Normally I'd push the parameters on the stack and use a call, but I'm sure D has some ability to do this, like apply(foo, args) would be the same as foo(args[0], ..., args[1]).
>>
>> I'm not concerned about type correctness, it should always be consistent between what I call and what is stored.
>>
>> Thanks.
>
> Like so?
>
> import std.variant;
>
> void foo(int a, string b, float c) {
> import std.stdio;
> writefln("a = %s, b = %s, c = %s", a, b, c);
> }
>
> auto apply(alias fn)(Variant[] values) {
> import std.traits : ParameterTypeTuple;
> import std.conv : emplace;
> alias Types = ParameterTypeTuple!fn;
> assert(values.length == Types.length);
> Types args = void;
> foreach(i, ref arg; args) {
> // using emplace instead of assignment here to be fully correct
> emplace!(typeof(arg))(&arg, values[i].get!(typeof(arg)));
> }
> return fn(args);
> }
>
> void main() {
> Variant[] values = [Variant(1), Variant("Hello world"), Variant(3.14159f)];
> apply!foo(values);
> }
The problem with this is that the function parameters need to be known. I do not know them. All I have is a function pointer and the arguments in variants.
So, it would work off
void bar(int, string, float) { }
void* foo = &bar;
Variant[] values = [Variant(1), Variant("Hello world"),
Variant(3.14159f)];
apply(foo, values);
So, it has to get the type from the variant at run time and pass the value's appropriately.
|
Copyright © 1999-2021 by the D Language Foundation