Thread overview
variadic (typesafe) args in DLL
Feb 08, 2008
Bjoern
Feb 08, 2008
Bjoern
February 08, 2008
Hi,
I hope that I can write a small utility DLL which offers support for :

BinaryOrPlus(WS_TABSTOP, WS_CHILD, WS_CLIPSIBLINGS)

Why ? Because my 4GL has no binary OR operator (just a function) so this code fragment will not work :

x is unsigned int = WS_TABSTOP | WS_CHILD | WS_CLIPSIBLINGS    // etc.

Instead I have to use :
(BinaryOr(BinaryOr(WS_TABSTOP , WS_CHILD), WS_CLIPSIBLINGS)  // stinks !

I hope it is possible to create something similar to :

export extern (Windows) uint BinaryOrPlus(uint...)
{
  uint result = _arguments[0];
  for (int i = 1; i < _arguments.length; i++)
  {
     result |= _arguments[i];
  }
  return result;
}

Unfortunately Error msg is :

C:\dmd\projects\bsdutil>dmd -profile -odc:\dmd\projects\bsdutil\obj -ofBSDUTIL.D
LL bsdutil.d demangle.d bsdutil.def
bsdutil.d(110): Error: undefined identifier _arguments
bsdutil.d(110): Error: _arguments must be an array or pointer type, not int

etc. I use Tango.
??????
Bjoern
February 08, 2008
"Bjoern" <nanali@nospam-wanadoo.fr> wrote in message news:foi37b$19vv$1@digitalmars.com...

> export extern (Windows) uint BinaryOrPlus(uint...)
> {
>   uint result = _arguments[0];
>   for (int i = 1; i < _arguments.length; i++)
>   {
>      result |= _arguments[i];
>   }
>   return result;
> }
>
> Unfortunately Error msg is :
>
> C:\dmd\projects\bsdutil>dmd -profile -odc:\dmd\projects\bsdutil\obj -ofBSDUTIL.D
> LL bsdutil.d demangle.d bsdutil.def
> bsdutil.d(110): Error: undefined identifier _arguments
> bsdutil.d(110): Error: _arguments must be an array or pointer type, not
> int

Ur typesafe variadic function, ur doin it wrong.

You declare the typesafe variadic param as so:

uint BinaryOrPlus(uint[] vals...)

then just use vals.

Typesafe variadic params are just sugar for passing an array literal.  In fact you can also pass an array reference in place of a list of params.

To that end, unless 4GL supports passing D arrays, you're going to have to do something else.


February 08, 2008
Jarrett Billingsley schrieb:
> "Bjoern" <nanali@nospam-wanadoo.fr> wrote in message news:foi37b$19vv$1@digitalmars.com...
> 
>> export extern (Windows) uint BinaryOrPlus(uint...)
>> {
>>   uint result = _arguments[0];
>>   for (int i = 1; i < _arguments.length; i++)
>>   {
>>      result |= _arguments[i];
>>   }
>>   return result;
>> }
>>
>> Unfortunately Error msg is :
>>
>> C:\dmd\projects\bsdutil>dmd -profile -odc:\dmd\projects\bsdutil\obj -ofBSDUTIL.D
>> LL bsdutil.d demangle.d bsdutil.def
>> bsdutil.d(110): Error: undefined identifier _arguments
>> bsdutil.d(110): Error: _arguments must be an array or pointer type, not int
> 
> Ur typesafe variadic function, ur doin it wrong.
> 
> You declare the typesafe variadic param as so:
> 
> uint BinaryOrPlus(uint[] vals...)
> 
> then just use vals.

How to iterate over vals  ?

> 
> Typesafe variadic params are just sugar for passing an array literal.  In fact you can also pass an array reference in place of a list of params.
> 
> To that end, unless 4GL supports passing D arrays, you're going to have to do something else. 

I can only use C style fixed arrays but this will end in code like
arr is fixed array on 3 uint = [WS_HONK, WS_TONK, WS_ITCH]
so, no win for me
> 
> 

okay let's forget about "typesafe" I can manage this in 4GL code, however following the D guidelines this should work :

export extern (Windows) uint BinaryOrPlus(uint firstarg, ...)
{
  uint result = firstarg; //_arguments[0];
  for (int i = 1; i < _arguments.length; i++)
  {
     result |= *cast(uint *)_argptr;
        _argptr += uint.sizeof;
  }
  return result;
}

In fact it don't work and it is looks dirty. they question here is ; what is the matter with _arguments /// using Tango

Thanks for spending your time
Bjoern
February 09, 2008
"Bjoern" <nanali@nospam-wanadoo.fr> wrote in message news:foic4a$1vk7$1@digitalmars.com...

>> You declare the typesafe variadic param as so:
>>
>> uint BinaryOrPlus(uint[] vals...)
>>
>> then just use vals.
>
> How to iterate over vals  ?

.. Uh, seriously?

It's an array.

> okay let's forget about "typesafe" I can manage this in 4GL code, however following the D guidelines this should work :
>
> export extern (Windows) uint BinaryOrPlus(uint firstarg, ...)
> {
>   uint result = firstarg; //_arguments[0];
>   for (int i = 1; i < _arguments.length; i++)
>   {
>      result |= *cast(uint *)_argptr;
>         _argptr += uint.sizeof;
>   }
>   return result;
> }
>
> In fact it don't work and it is looks dirty. they question here is ; what is the matter with _arguments /// using Tango

extern(Windows) variadic functions don't have an _arguments parameter, only extern(D) variadic functions do.

According to the spec, extern(C) (and maybe Windows, it doesn't say) are supposed to have an _argptr parameter but it doesn't seem to work :\

So, since you're basically writing a C function, you have to do it the C way: with va_start and the like.

In phobos it's in std.c.stdarg, and in Tango, tango.stdc.stdarg.  You'd do something like:

export extern(Windows) uint BinOr(uint firstarg, ...)
{
    va_list args;
    va_start(args, firstarg);

    // it's up to you to figure out the end of the list!
    // isn't that fun?

    va_end(args);
}

Lastly -- why _are_ you using this bizarre language anyway?