www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - variadic (typesafe) args in DLL

reply Bjoern <nanali nospam-wanadoo.fr> writes:
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
Feb 08 2008
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"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.
Feb 08 2008
parent reply Bjoern <nanali nospam-wanadoo.fr> writes:
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
Feb 08 2008
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"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?
Feb 09 2008