Re: opDispatch with string mixin does not work as I would expect.

2018-02-09 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 10 February 2018 at 06:32:43 UTC, German Diago wrote:

Hello everyone,

I am trying to forward some member functions from a struct as a 
Catch-all function, so I did something like this:


struct A {
struct HeaderData {
  align(1):
  char [21] id;
  ubyte field1;
  ubyte field2;
}

Nullable!(HeaderData) headerData;


auto opDispatch(string name)() {
  readHeader();
  static foreach (member; __traits(allMembers, 
HeaderData)) {

 static if (name == member) {
 return mixin("headerData." ~ name);
 }
  }
  }

The mixin line does not work. I want to generate the access to 
the field. How could I achieve that?


That looks like it should work. Perhaps you need to change
`static if (name == member)` to
`static if (name == member.stringof)`

Alternatively you could do something like

auto opDispatch(string name)() 
if(hasMember!(HeaderData,name){

  readHeader();
  return mixin("headerData." ~ name);
}




Re: opDispatch with string mixin does not work as I would expect.

2018-02-09 Thread Boris-Barboris via Digitalmars-d-learn

On Saturday, 10 February 2018 at 06:32:43 UTC, German Diago wrote:
The mixin line does not work. I want to generate the access to 
the field. How could I achieve that?



struct Outer
{
struct Inner
{
int a;
float b;
}
Inner i;

auto opDispatch(string name)()
{
return __traits(getMember, i, name);
}
}



opDispatch with string mixin does not work as I would expect.

2018-02-09 Thread German Diago via Digitalmars-d-learn

Hello everyone,

I am trying to forward some member functions from a struct as a 
Catch-all function, so I did something like this:


struct A {
struct HeaderData {
  align(1):
  char [21] id;
  ubyte field1;
  ubyte field2;
}

Nullable!(HeaderData) headerData;


auto opDispatch(string name)() {
  readHeader();
  static foreach (member; __traits(allMembers, 
HeaderData)) {

 static if (name == member) {
 return mixin("headerData." ~ name);
 }
  }
  }

The mixin line does not work. I want to generate the access to 
the field. How could I achieve that?


Re: typedef behavior

2018-02-09 Thread Alex via Digitalmars-d-learn

On Saturday, 10 February 2018 at 02:08:50 UTC, Alex wrote:
Inside of the struct E I define more then one static array. 
Namely, one for each Typedef I plan to instantiate. The 
Typedefs have to be known at compile time, so the amount of 
them has to be known by me :)
Then, during the initialization, I work only with one of the 
arrays of E, depending on the Typedef I use.
During the work inside of E, the object will have to check, 
which array was initialized and cooperate with this array, as 
this is the only possibility.


Hmm... No. As the arrays are shared all of them will be 
initialized for every Typedef and the last point (decision during 
the work inside of a single Typedef) can not be achieved. So... 
there has to be another indirection, which will be filled during 
(possibly static) initialization.


Re: Run-time initialised static variables

2018-02-09 Thread dekevin via Digitalmars-d-learn

On Tuesday, 6 February 2018 at 23:03:07 UTC, dekevin wrote:

Hello everyone,
I just ran into the problem, that I need a static variable, 
where the initialisation code for that variable is only 
accessible during run-time (since part of the initialisation 
code will be dynamically linked).


Is there a way to do this in D?

To be a bit more concrete, this is where I have the problem 
(where ℚ uses GMP, which is dynamically linked):


struct ℚInf {
   ℚ qval;
   immutable static ℚInf zero = ℚInf(0,1);
   this(long num, long den) {
qval = ℚ(num,den); //this initialisation requires 
dynamically linked code

}
}


In case anyone is curios, thanks to tgehr i was able to resolve 
the issue.

For static variables:
struct ℚInf {
ℚ qval;
static ℚInf zero = void;
static this() {
zero = ℚInf(0,1);
}
 }

For immutable static variables (a bit hacky since it sidesteps 
the type system):

struct ℚInf {
ℚ qval;
immutable static ℚInf zero = void;
static this() @trusted {
import std.conv: emplace;
emplace!ℚInf(cast(ℚInf*),ℚInf(0,1));
}
 }



Re: typedef behavior

2018-02-09 Thread Alex via Digitalmars-d-learn

On Saturday, 10 February 2018 at 01:23:20 UTC, Ali Çehreli wrote:

>
> Yup. They are shared by two Typedef instantiations with
different cookies.
>
> So...
> The question is two-fold:
> Would it help to alter the init value of the Typedef?
> If yes, how to alter it?
> If no, is this a bug?

I think this is a limitation of Typedef.

I can't see a way out (at least one that can support any type 
E). It should be possible if you can modify E but I can't work 
something out now.


Ali


Ah... From your hint I arrived at the following:

Inside of the struct E I define more then one static array. 
Namely, one for each Typedef I plan to instantiate. The Typedefs 
have to be known at compile time, so the amount of them has to be 
known by me :)
Then, during the initialization, I work only with one of the 
arrays of E, depending on the Typedef I use.
During the work inside of E, the object will have to check, which 
array was initialized and cooperate with this array, as this is 
the only possibility.


As a workaround this will work, I think... Thanks!

Nevertheless, I would file a bug later on... all ideas are 
appreciated in the meanwhile.


Re: typedef behavior

2018-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 02/09/2018 05:14 PM, Alex wrote:

>> > struct E
>> > {
>> >  size_t i;
>> >  static T[] tarr;
>>
>> To save time to others, note that 'tarr' is a static member that ends
>> up being shared by two Typedef instantiations.
>
> Yup. They are shared by two Typedef instantiations with different 
cookies.

>
> So...
> The question is two-fold:
> Would it help to alter the init value of the Typedef?
> If yes, how to alter it?
> If no, is this a bug?

I think this is a limitation of Typedef.

I can't see a way out (at least one that can support any type E). It 
should be possible if you can modify E but I can't work something out now.


Ali



Re: typedef behavior

2018-02-09 Thread Alex via Digitalmars-d-learn

On Saturday, 10 February 2018 at 01:01:39 UTC, Ali Çehreli wrote:

On 02/09/2018 03:45 PM, Alex wrote:
> A question about Typedef usage:
> Say, I have the following circumstances
>
> /// --- code --- ///
>
> import std.typecons;
>
> void main()
> {
>  MyEA ea;
>  MyEB eb;
>  ea.tarr.length = 5;
>  static assert(!is(MyEA == MyEB));
>  static assert(!is(MyEA == E));
>  static assert(!is(MyEB == E));
>  assert(ea.tarr.length == eb.tarr.length); // line 11
>  assert(ea.tarr.length != eb.tarr.length); // line 12

You must have meant

 assert(ea.tarr.ptr != eb.tarr.ptr); // line 12

Indeed, .ptr are unexpectedly the same.



Yes... this is a more precise comparison :)


> }
>
> struct T
> {
>  size_t i;
> }
>
> struct E
> {
>  size_t i;
>  static T[] tarr;

To save time to others, note that 'tarr' is a static member 
that ends up being shared by two Typedef instantiations.


Yup. They are shared by two Typedef instantiations with different 
cookies.


So...
The question is two-fold:
Would it help to alter the init value of the Typedef?
If yes, how to alter it?
If no, is this a bug?



> }
>
> alias MyEA = Typedef!(E, E.init, "A"); // line 26
> alias MyEB = Typedef!(E, E.init, "B"); // line 27
>
> /// --- code ends --- ///
>
> Line 12 yields an assertion error, while line 11 does not.
> This tells me, that despite the fact the types MyEA and MyEB
are
> different they still share the static array, which would
contradict the
> definition of static.
>
> I suppose, the tricky thing is to tweak the init property of
the
> typedefs in lines 26/27 to avoid this clash. How to manage
this?

Ali


Re: typedef behavior

2018-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 02/09/2018 03:45 PM, Alex wrote:
> A question about Typedef usage:
> Say, I have the following circumstances
>
> /// --- code --- ///
>
> import std.typecons;
>
> void main()
> {
>  MyEA ea;
>  MyEB eb;
>  ea.tarr.length = 5;
>  static assert(!is(MyEA == MyEB));
>  static assert(!is(MyEA == E));
>  static assert(!is(MyEB == E));
>  assert(ea.tarr.length == eb.tarr.length); // line 11
>  assert(ea.tarr.length != eb.tarr.length); // line 12

You must have meant

 assert(ea.tarr.ptr != eb.tarr.ptr); // line 12

Indeed, .ptr are unexpectedly the same.

> }
>
> struct T
> {
>  size_t i;
> }
>
> struct E
> {
>  size_t i;
>  static T[] tarr;

To save time to others, note that 'tarr' is a static member that ends up 
being shared by two Typedef instantiations.


> }
>
> alias MyEA = Typedef!(E, E.init, "A"); // line 26
> alias MyEB = Typedef!(E, E.init, "B"); // line 27
>
> /// --- code ends --- ///
>
> Line 12 yields an assertion error, while line 11 does not.
> This tells me, that despite the fact the types MyEA and MyEB are
> different they still share the static array, which would contradict the
> definition of static.
>
> I suppose, the tricky thing is to tweak the init property of the
> typedefs in lines 26/27 to avoid this clash. How to manage this?

Ali



typedef behavior

2018-02-09 Thread Alex via Digitalmars-d-learn

A question about Typedef usage:
Say, I have the following circumstances

/// --- code --- ///

import std.typecons;

void main()
{
MyEA ea;
MyEB eb;
ea.tarr.length = 5;
static assert(!is(MyEA == MyEB));
static assert(!is(MyEA == E));
static assert(!is(MyEB == E));
assert(ea.tarr.length == eb.tarr.length); // line 11
assert(ea.tarr.length != eb.tarr.length); // line 12
}

struct T
{
size_t i;
}

struct E
{
size_t i;
static T[] tarr;
}

alias MyEA = Typedef!(E, E.init, "A"); // line 26
alias MyEB = Typedef!(E, E.init, "B"); // line 27

/// --- code ends --- ///

Line 12 yields an assertion error, while line 11 does not.
This tells me, that despite the fact the types MyEA and MyEB are 
different they still share the static array, which would 
contradict the definition of static.


I suppose, the tricky thing is to tweak the init property of the 
typedefs in lines 26/27 to avoid this clash. How to manage this?


Re: Error in template instantiation from D-Cookbook example

2018-02-09 Thread ShadoLight via Digitalmars-d-learn

On Friday, 9 February 2018 at 21:39:22 UTC, Adam D. Ruppe wrote:

On Friday, 9 February 2018 at 21:31:29 UTC, ShadoLight wrote:

[1] https://run.dlang.io/is/dyElXg


There's missing quotes in there:

Line 14:
code ~= "push(call!"~piece~"(pop(), pop()));\n";

Should be:

code ~= "push(call!\""~piece~"\"(pop(), pop()));\n";

[snip]

On Friday, 9 February 2018 at 21:58:51 UTC, Meta wrote:

On Friday, 9 February 2018 at 21:31:29 UTC, ShadoLight wrote:

[snip]
The problem becomes apparent once you uncomment one of these 
and paste the offending string ("5 5 + 3 - 2 * 1 + 3 /") in.

[snip]

push(call!+(pop(), pop()));

[snip]
So it takes a string as its sole template argument. The problem 
is that the code in convertToD forgot to add the quotes around 
the operators that are supposed to be passed as strings to call.

[snip]

Indeed, that makes sense! Thanks to you both!

Adam, you are right - it was indeed incorrectly mangled... it is 
shown as...

code ~= "push(call!'"~piece~"'(pop(), pop()));\n";

So the escaped quotes \" were mangled as '. I simply removed them 
since I assumed they were typos in the doc, similar to the other 
ones I had fixed. My bad.


Man, I cannot believe how quickly you guys answered. Thanks again!


Re: Error in template instantiation from D-Cookbook example

2018-02-09 Thread Meta via Digitalmars-d-learn

On Friday, 9 February 2018 at 21:31:29 UTC, ShadoLight wrote:

writeln(parse(code));   // to aid with debugging
writeln(convertToD(parse(code)));   // debugging aid
..to..
writeln(parse(code)[]); // to aid with debugging
writeln(convertToD(parse(code))[]); // debugging aid


The problem becomes apparent once you uncomment one of these and 
paste the offending string ("5 5 + 3 - 2 * 1 + 3 /") in. 
`writeln(convertToD(parse("5 5 + 3 - 2 * 1 + 3 /"))[]);` prints 
the following:


push(5);
push(5);
push(call!+(pop(), pop()));
push(3);
push(call!-(pop(), pop()));
push(2);
push(call!*(pop(), pop()));
push(1);
push(call!+(pop(), pop()));
push(3);
push(call!/(pop(), pop()));

If you look at the definition of call:

int call(string op)(int a, int b) {
return mixin("b"~op~"a");
}

So it takes a string as its sole template argument. The problem 
is that the code in convertToD forgot to add the quotes around 
the operators that are supposed to be passed as strings to call. 
If you modify line 14 from the example you pasted to add these 
quotes to the mixin string, it works:


code ~= "push(call!"~piece~"(pop(), pop()));\n";

becomes

code ~= "push(call!\""~piece~"\"(pop(), pop()));\n";

Running the modified code, it prints:

push(5);
push(5);
push(call!"+"(pop(), pop()));
push(3);
push(call!"-"(pop(), pop()));
push(2);
push(call!"*"(pop(), pop()));
push(1);
push(call!"+"(pop(), pop()));
push(3);
push(call!"/"(pop(), pop()));

And `runDslCode!"5 5 + 3 - 2 * 1 + 3 /"();` prints `[5]`.


Re: Error in template instantiation from D-Cookbook example

2018-02-09 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 9 February 2018 at 21:31:29 UTC, ShadoLight wrote:

[1] https://run.dlang.io/is/dyElXg


There's missing quotes in there:

Line 14:
code ~= "push(call!"~piece~"(pop(), pop()));\n";

Should be:

code ~= "push(call!\""~piece~"\"(pop(), pop()));\n";


That might have been an error in the original book. A lot of 
quotes and semicolons got mangled in the process of copying them 
from the actual compilable examples into the MS Word manuscript..


But to explain why this is wrong just consider the code generated:

push(call!+(pop(), pop()));


When the operator is pasted in without quotes, you get the above. 
And + isn't a valid template arg. But "+" is.


Error in template instantiation from D-Cookbook example

2018-02-09 Thread ShadoLight via Digitalmars-d-learn

Hi,

Trying to improve my CT-fu, I looked at a DSL example (chapter 9) 
in Adam's D-Cookbook. Although I am sure Adam's original examples 
would have worked, there were some errors in the example code in 
the book.


The example also contains some code to allow you to test the 
functions at RT, which had an error i.e. I had to change this...


writeln(parse(code));   // to aid with debugging
writeln(convertToD(parse(code)));   // debugging aid
..to..
writeln(parse(code)[]); // to aid with debugging
writeln(convertToD(parse(code))[]); // debugging aid

..to match the actual function arguments. So that worked fine.

However I could not get the CT version to work with the current 
version of DMD i.e. this [1]...


[1] https://run.dlang.io/is/dyElXg

...fails with:
onlineapp.d-mixin-36(38): Error: template argument expected 
following !
onlineapp.d(48): Error: template instance onlineapp.runDslCode!"5 
5 + 3 - 2 * 1 + 3 /" error instantiating.


I find the error message a bit lacking as to the real cause - I 
really cannot see where the "template argument expected following 
!" error is. It all looks correct to me.


In addition the RT version is working correctly (after fixing the 
above bug), so that is not helping in identifying the error - 
particularly since it is failing in the only CT specific function 
not used/called at RT. So I am not sure how to debug this.


Can somebody please put me out of my misery here?

Thx!



Re: Elegant way to use dynamic bindings

2018-02-09 Thread Dennis via Digitalmars-d-learn

On Friday, 9 February 2018 at 18:14:06 UTC, Mike Wey wrote:
You may need to pass `/s` to implib so it will add the 
underscore to the symbol in the import library. If it's 
actually needed depends on what the dll uses.


That did it, now both dynamic loading and dynamic linking work. 
:) Thanks both of you.


I'd still like to find a nice way to generate the boilerplate 
code for dynamic loading, if I come up with something I'll post 
it here.


Re: Debugging on Windows

2018-02-09 Thread Benjamin Thaut via Digitalmars-d-learn

On Thursday, 8 February 2018 at 21:09:33 UTC, JN wrote:

Hi,

is there any way to debug binaries on Windows? I'd at least 
like to know which line of code made it crash. If it's D code, 
I get a call trace usually, but if it's a call to a C library, 
I get a crash and that's it. I am using VSCode and I'd prefer 
to debug in it if possible, but using other IDEs is a 
possibility for me if that will help.


The best option most likely is to get the Visual Studio Community 
Edition and then Install the VisualD extension for Visual Studio. 
This will give you a very good debugging experience with a 
bulitin D expression evaulator and the usual features the very 
good Visual Studio debugger comes with.


Kind Regards
Benjamin Thaut


Re: Elegant way to use dynamic bindings

2018-02-09 Thread Mike Wey via Digitalmars-d-learn

On 09-02-18 15:04, Dennis wrote:
I read the Derelict documentation a while ago, I didn't grasp all of it. 
Reading it again, I can now make sense of it though. :)


On Friday, 9 February 2018 at 12:53:44 UTC, Mike Parker wrote:
Did you link with the library you created with implib? That linker 
error suggests you didn't.


I added `pragma(lib, "mupen64plus.lib");` above the extern(C) block.
Adding `libs "mupen64plus"` to dub.sdl doesn't make a difference.

The thing that confuses me is that the import lib has symbols without 
underscore prefix (I see them when running `libunres -p 
mupen64plus.lib`), but when I change the function pointer declaration 
into a function declaration it tries to link "_CoreGetAPIVersions" and 
can't find it.


I put the .dll's in the root of the project directory by the way. Does 
that count as a "system library search path"?


You may need to pass `/s` to implib so it will add the underscore to the 
symbol in the import library. If it's actually needed depends on what 
the dll uses.


--
Mike Wey


Re: Debugging bad requests with vibe

2018-02-09 Thread rjframe via Digitalmars-d-learn
On Fri, 09 Feb 2018 15:48:54 +, Nicholas Wilson wrote:

> On Friday, 9 February 2018 at 08:06:53 UTC, Seb wrote:
>> On Thursday, 8 February 2018 at 17:09:44 UTC, Nicholas Wilson wrote:
>>> Is there a way I can see/log what requests are being made? I can
>>> change both the client and server.
>>
>> -v and -vv
> 
> So it turns out that structs do not work as parameters TO rest interface
> functions.
> 
> https://github.com/vibe-d/vibe.d/issues/2067

I have a project doing this; I think I solved that (or something) with:

```
@path("/api/")
interface RestAPI {
// stuff
}
```

I cannot reproduce your problem with that code though to see if it will 
work.


Re: uint[3] not equivalent to void[12]?

2018-02-09 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Feb 09, 2018 at 03:05:33PM +, Ralph Doncaster via 
Digitalmars-d-learn wrote:
> This seems odd to me.  Is there a way I can make a function that takes
> an array of any type but only of a specific size in bytes?
> 
> void.d(8): Error: function void.foo (void[12] arr) is not callable
> using argument types (uint[3])
> Failed: ["/usr/bin/dmd", "-v", "-o-", "void.d", "-I."]
> void foo(void [12] arr)
> {
> }
> 
> void main()
> {
> uint[3] arr;
> foo(arr);
> }

You probably didn't mean to pass a static array, because those are
passed by value and may entail unnecessary copying. (Though in this
case, if you're only expecting 12 bytes, that's not that big of a
difference.)

But in any case, probably something like this would do:

void foo(void[] arr)
in { assert(arr.length == 12); }
do {
...
}


T

-- 
If creativity is stifled by rigid discipline, then it is not true creativity.


Re: uint[3] not equivalent to void[12]?

2018-02-09 Thread Ralph Doncaster via Digitalmars-d-learn

On Friday, 9 February 2018 at 16:28:50 UTC, Nicholas Wilson wrote:
On Friday, 9 February 2018 at 15:50:24 UTC, Ralph Doncaster 
wrote:
Is there a way I can make a function that takes an array of any 
type but only of a specific size in bytes?


With a template that constrains the types size:

void foo(T)(T t) if (T.sizeof == 12)
{
//...
}

alternately reject incorrect values at runtime

void foo(ubyte[] t)
in
{
assert(t.length == 12);
}
do
{
//...
}


Thanks.  That's what I thought.  If I stick with using D, I'll 
probably go with the runtime check.




Re: uint[3] not equivalent to void[12]?

2018-02-09 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 9 February 2018 at 15:50:24 UTC, Ralph Doncaster wrote:

On Friday, 9 February 2018 at 15:24:27 UTC, Mike Parker wrote:
On Friday, 9 February 2018 at 15:05:33 UTC, Ralph Doncaster 
wrote:
This seems odd to me.  Is there a way I can make a function 
that takes an array of any type but only of a specific size 
in bytes?


void.d(8): Error: function void.foo (void[12] arr) is not 
callable using argument types (uint[3])

Failed: ["/usr/bin/dmd", "-v", "-o-", "void.d", "-I."]
void foo(void [12] arr)
{
}

void main()
{
uint[3] arr;
foo(arr);
}


void has no size, so what does it mean to have 12 of them?


according to the docs and my testing, the size of a void array 
element is 1,


Correct.


so the following code prints 12:
import std.stdio;

void foo(void [] arr)
{
writeln("length: " arr.length);
}

void main()
{
uint[3] arr;
foo(arr);
}

I thought about using templates, but I was looking for a simple 
way of making a function that takes an array of 12 bytes, 
whether it is uint[3], ubyte[12], or ushort[6].


uint[3] and void[12] have the same size but are different types 
so the compiler will reject it.
you can reinterpret cast them(i.e. *cast(void[12])() ), but 
this is a rather blunt tool. Is it safe in the case that the 
types size is at least 12 but not safe in general.


Is there a way I can make a function that takes an array of any 
type but only of a specific size in bytes?


With a template that constrains the types size:

void foo(T)(T t) if (T.sizeof == 12)
{
//...
}

alternately reject incorrect values at runtime

void foo(ubyte[] t)
in
{
assert(t.length == 12);
}
do
{
//...
}



Re: uint[3] not equivalent to void[12]?

2018-02-09 Thread Ralph Doncaster via Digitalmars-d-learn

On Friday, 9 February 2018 at 15:24:27 UTC, Mike Parker wrote:
On Friday, 9 February 2018 at 15:05:33 UTC, Ralph Doncaster 
wrote:
This seems odd to me.  Is there a way I can make a function 
that takes an array of any type but only of a specific size in 
bytes?


void.d(8): Error: function void.foo (void[12] arr) is not 
callable using argument types (uint[3])

Failed: ["/usr/bin/dmd", "-v", "-o-", "void.d", "-I."]
void foo(void [12] arr)
{
}

void main()
{
uint[3] arr;
foo(arr);
}


void has no size, so what does it mean to have 12 of them?


according to the docs and my testing, the size of a void array 
element is 1, so the following code prints 12:

import std.stdio;

void foo(void [] arr)
{
writeln("length: " arr.length);
}

void main()
{
uint[3] arr;
foo(arr);
}

I thought about using templates, but I was looking for a simple 
way of making a function that takes an array of 12 bytes, whether 
it is uint[3], ubyte[12], or ushort[6].




Re: Debugging bad requests with vibe

2018-02-09 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 9 February 2018 at 08:06:53 UTC, Seb wrote:
On Thursday, 8 February 2018 at 17:09:44 UTC, Nicholas Wilson 
wrote:
Is there a way I can see/log what requests are being made? I 
can change both the client and server.


-v and -vv


So it turns out that structs do not work as parameters TO rest 
interface functions.


https://github.com/vibe-d/vibe.d/issues/2067


Re: Elegant way to use dynamic bindings

2018-02-09 Thread Dennis via Digitalmars-d-learn

On Friday, 9 February 2018 at 14:51:30 UTC, Mike Parker wrote:
Where was the lib file located? Was it in the root project 
directory? How are you compiling your project? What does your 
directory tree look like?

(...)
That depends. Is that the directory where your executable is 
written? Are you launching it from inside an Visual Studio or 
from the command line? Normally, the executable's directory is 
on the system path, but when using VS the default configuration 
is to write the executables into configuration-specific 
subdirectories.


I use `dub run` from cmd or Mono-D. All .exe, .lib and .dll files 
are in the root. Source files are in the subdirectory 'source'.


I tried to reduce the problem by making a simple test folder 
containing the necessary .dll files, import library and source 
files:


freetype6.dll
libpng12.dll
libpng3.dll
main.d
main.exe
main.obj
mupen64plus-audio-sdl.dll
mupen64plus-input-sdl.dll
mupen64plus-rsp-hle.dll
mupen64plus-video-glide64mk2.dll
mupen64plus-video-rice.dll
mupen64plus.dll
mupen64plus.lib
SDL.dll
zlib1.dll

Where main.d is:
```
import std.stdio;

version(dynamiclink) {

pragma(lib, "mupen64plus.lib");
extern(C) nothrow @nogc {
int CoreGetAPIVersions(int*, int*, int*, int*);
}

int main() {
int a, b, c, d;
CoreGetAPIVersions(, , , );
writeln("Version: ", a, " - ", b, " - ", c, " - ", d);
return 0;
}
}

version(dynamicload) {

	import core.sys.windows.windows: LoadLibrary, GetProcAddress, 
GetLastError;
	extern(C) alias p_CoreGetAPIVersions = int function(int*, int*, 
int*, int*);

p_CoreGetAPIVersions CoreGetAPIVersions;

int main() {
auto handle = LoadLibrary("mupen64plus.dll");
		CoreGetAPIVersions = cast(p_CoreGetAPIVersions) 
GetProcAddress(handle, "CoreGetAPIVersions");


int a, b, c, d;
CoreGetAPIVersions(, , , );
writeln("Version: ", a, " - ", b, " - ", c, " - ", d);
return 0;
}
}
```

With `dmd main.d -version=dynamicload` it works, but with `dmd 
main.d -version=dynamiclink` it still gives this:


main.obj(main)
Error 42: Symbol Undefined _CoreGetAPIVersions
Error: linker exited with status 1


Re: uint[3] not equivalent to void[12]?

2018-02-09 Thread Mike Parker via Digitalmars-d-learn

On Friday, 9 February 2018 at 15:24:27 UTC, Mike Parker wrote:




import std.stdio;

enum numBytes = 12;
void foo(T, size_t N)(T[N] arr)
if((N * T.sizeof) == numBytes)
{
writeln(arr);
}

void bar(ubyte[12] arr)
{
writeln(arr);
}


Also, it's worth mentioning in case you aren't aware that this 
can be expensive, depending on the size of the array. Static 
arrays are passed by value. You may want to make the arr 
parameters ref or, if you want to protect the contents, const ref:


void foo(T, size_t N)(ref const(T)[N] arr)


Re: uint[3] not equivalent to void[12]?

2018-02-09 Thread Mike Parker via Digitalmars-d-learn

On Friday, 9 February 2018 at 15:05:33 UTC, Ralph Doncaster wrote:
This seems odd to me.  Is there a way I can make a function 
that takes an array of any type but only of a specific size in 
bytes?


void.d(8): Error: function void.foo (void[12] arr) is not 
callable using argument types (uint[3])

Failed: ["/usr/bin/dmd", "-v", "-o-", "void.d", "-I."]
void foo(void [12] arr)
{
}

void main()
{
uint[3] arr;
foo(arr);
}


void has no size, so what does it mean to have 12 of them?

Here are a couple of options, depending on what you need.


import std.stdio;

enum numBytes = 12;
void foo(T, size_t N)(T[N] arr)
if((N * T.sizeof) == numBytes)
{
writeln(arr);
}

void bar(ubyte[12] arr)
{
writeln(arr);
}

void main()
{
uint[3] arr = [20, 10, 1];
foo(arr);
bar(cast(ubyte[12])arr);
}
===

Output:
[20, 10, 1]
[20, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0]


uint[3] not equivalent to void[12]?

2018-02-09 Thread Ralph Doncaster via Digitalmars-d-learn
This seems odd to me.  Is there a way I can make a function that 
takes an array of any type but only of a specific size in bytes?


void.d(8): Error: function void.foo (void[12] arr) is not 
callable using argument types (uint[3])

Failed: ["/usr/bin/dmd", "-v", "-o-", "void.d", "-I."]
void foo(void [12] arr)
{
}

void main()
{
uint[3] arr;
foo(arr);
}



Re: Elegant way to use dynamic bindings

2018-02-09 Thread Mike Parker via Digitalmars-d-learn

On Friday, 9 February 2018 at 14:04:05 UTC, Dennis wrote:

I added `pragma(lib, "mupen64plus.lib");` above the extern(C) 
block.
Adding `libs "mupen64plus"` to dub.sdl doesn't make a 
difference.


Where was the lib file located? Was it in the root project 
directory? How are you compiling your project? What does your 
directory tree look like?




The thing that confuses me is that the import lib has symbols 
without underscore prefix (I see them when running `libunres -p 
mupen64plus.lib`), but when I change the function pointer 
declaration into a function declaration it tries to link 
"_CoreGetAPIVersions" and can't find it.


Yes, the underscore is normally prepended to cdecl functions on 
Windows. It makes no difference if your function prototypes are 
properly declared.




I put the .dll's in the root of the project directory by the 
way. Does that count as a "system library search path"?


That depends. Is that the directory where your executable is 
written? Are you launching it from inside an Visual Studio or 
from the command line? Normally, the executable's directory is on 
the system path, but when using VS the default configuration is 
to write the executables into configuration-specific 
subdirectories.


Re: Elegant way to use dynamic bindings

2018-02-09 Thread Dennis via Digitalmars-d-learn
I read the Derelict documentation a while ago, I didn't grasp all 
of it. Reading it again, I can now make sense of it though. :)


On Friday, 9 February 2018 at 12:53:44 UTC, Mike Parker wrote:
Did you link with the library you created with implib? That 
linker error suggests you didn't.


I added `pragma(lib, "mupen64plus.lib");` above the extern(C) 
block.

Adding `libs "mupen64plus"` to dub.sdl doesn't make a difference.

The thing that confuses me is that the import lib has symbols 
without underscore prefix (I see them when running `libunres -p 
mupen64plus.lib`), but when I change the function pointer 
declaration into a function declaration it tries to link 
"_CoreGetAPIVersions" and can't find it.


I put the .dll's in the root of the project directory by the way. 
Does that count as a "system library search path"?


Re: Debugging bad requests with vibe

2018-02-09 Thread tetyys via Digitalmars-d-learn

On Friday, 9 February 2018 at 11:46:31 UTC, Nicholas Wilson wrote:

On Friday, 9 February 2018 at 08:06:53 UTC, Seb wrote:
On Thursday, 8 February 2018 at 17:09:44 UTC, Nicholas Wilson 
wrote:
Is there a way I can see/log what requests are being made? I 
can change both the client and server.


-v and -vv


All that gives me is a bunch of
[FAC3BFF6:FAC451F6 dia] Actively closing TCP connection

is there a way to get the JSON being sent?


Try Fiddler, great tool too


Re: Elegant way to use dynamic bindings

2018-02-09 Thread Mike Parker via Digitalmars-d-learn

On Friday, 9 February 2018 at 12:15:04 UTC, Dennis wrote:



I presume the .dll isn't loaded properly (if at all), but I 
can't find a load function in the .lib and don't know how to 
debug this. So I guess I'll just do it manually since that 
works, but does anyone have some tips to make .dll bindings 
elegantly?


I suggest you read this first:

http://derelictorg.github.io/bindings/

It explains the difference between dynamic bindings and static 
bindings. The important thing to understand is that both types 
can be used with DLLs, but only static bindings can be use with 
static libraries.


Dynamic bindings have no link time dependency on the DLL and the 
DLL must be loaded manually. Static bindings have a link time 
dependency and can be linked with either a static library, an 
import library (on Windows -- what you get when you run implib or 
compile a DLL yourself), or directly with a shared object (.so) 
on non-Windows systems (and probably .dylib/Frameworks on Mac).


Dynamic bindings use function pointer because that's the only way 
to do manuall loading. For static bindings, you use normal 
function declarations and the OS will load the DLL automatically 
when the app starts up (dynamic loading) if you've linked to an 
import library or .so, and, of course, will load nothing if 
you've linked to a static library.


Some Derelict packages, like DerelictSDL2 and DerelictGLFW3, 
support both dynamic and static binding. For the former, the 
function pointer declarations and the loader are all in [1]. For 
the latter, there is no loader and the declarations are all in 
[2].


[1] 
https://github.com/DerelictOrg/DerelictGLFW3/blob/master/source/derelict/glfw3/dynload.d


[2] 
https://github.com/DerelictOrg/DerelictGLFW3/blob/master/source/derelict/glfw3/statfun.d


So if you don't need to load manually and don't mind the 
link-time dependency on the C library, then you can use normal 
function declarations in your binding:


extern(C) @nogc nothrow {
void foo();
}



Re: Elegant way to use dynamic bindings

2018-02-09 Thread Mike Parker via Digitalmars-d-learn

On Friday, 9 February 2018 at 12:15:04 UTC, Dennis wrote:

I found the IMPLIB tool 
(http://www.digitalmars.com//ctg/implib.html) and made a .lib 
for the .dll and at first I got:


Error 42: Symbol Undefined _CoreGetAPIVersions
Error: linker exited with status 1



Forgot to address this in the previous post.

Did you link with the library you created with implib? That 
linker error suggests you didn't.


Elegant way to use dynamic bindings

2018-02-09 Thread Dennis via Digitalmars-d-learn
I want to bind to a .dll on Windows, so I looked at how Derelict 
packages are doing it and found it does it like this:


```
extern(C) {
  alias da_CoreGetAPIVersions = m64p_error 
function(int*,int*,int*,int*);

  ...
}

__gshared {
  da_CoreGetAPIVersions CoreGetAPIVersions;
  ...
}

protected override void loadSymbols() {
  bindFunc(cast(void**),"CoreGetAPIVersions");
  ...
```
I don't like how each function name is repeated 4 times. 
Preferably, I'd write it like a static library:

```
extern(C) {
  ///documentation
  m64p_error CoreGetAPIVersions(int*,int*,int*,int*);
}
```
And then use some reflection and mixins to make it work for 
dynamic bindings.
I found the IMPLIB tool 
(http://www.digitalmars.com//ctg/implib.html) and made a .lib for 
the .dll and at first I got:


Error 42: Symbol Undefined _CoreGetAPIVersions
Error: linker exited with status 1

So apparently, you got to bind functions pointers, not functions.
```
extern(C) {
  ///documentation
  m64p_error function(int*,int*,int*,int*) CoreGetAPIVersions;
}
```
But then I get:
object.Error@(0): Access Violation

I presume the .dll isn't loaded properly (if at all), but I can't 
find a load function in the .lib and don't know how to debug 
this. So I guess I'll just do it manually since that works, but 
does anyone have some tips to make .dll bindings elegantly?




Re: Debugging bad requests with vibe

2018-02-09 Thread Arjan via Digitalmars-d-learn

On Friday, 9 February 2018 at 11:46:31 UTC, Nicholas Wilson wrote:

On Friday, 9 February 2018 at 08:06:53 UTC, Seb wrote:
On Thursday, 8 February 2018 at 17:09:44 UTC, Nicholas Wilson 
wrote:
Is there a way I can see/log what requests are being made? I 
can change both the client and server.


-v and -vv


All that gives me is a bunch of
[FAC3BFF6:FAC451F6 dia] Actively closing TCP connection

is there a way to get the JSON being sent?


Wireshark?


Re: Debugging bad requests with vibe

2018-02-09 Thread Nicholas Wilson via Digitalmars-d-learn
On Thursday, 8 February 2018 at 20:24:19 UTC, Nicholas Wilson 
wrote:
On Thursday, 8 February 2018 at 17:09:44 UTC, Nicholas Wilson 
wrote:
I have set up a vibe.d rest interface (on a server) and have a 
client on my machine.


struct Observation
{
string desc;
DateTime time;
}

interface Obsever
{
@property void observe(Observation ra);
}

void main()
{
auto test = Observation("a duck", 
cast(DateTime)Clock.currTime(UTC()));


auto client = new RestInterfaceClient! 
Obsever("http://example.com/observation;);

client. observe = test; // 400
}

I' pretty sure the url is correct because other ones give 404.

Is there a way I can see/log what requests are being made? I 
can change both the client and server.


Never mind, it was because I was accidentally shadowing that 
path with a get on the server.


Hmm, nope it wasn't that.


Re: Debugging bad requests with vibe

2018-02-09 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 9 February 2018 at 08:06:53 UTC, Seb wrote:
On Thursday, 8 February 2018 at 17:09:44 UTC, Nicholas Wilson 
wrote:
Is there a way I can see/log what requests are being made? I 
can change both the client and server.


-v and -vv


All that gives me is a bunch of
[FAC3BFF6:FAC451F6 dia] Actively closing TCP connection

is there a way to get the JSON being sent?


Re: Debugging on Windows

2018-02-09 Thread Rene Zwanenburg via Digitalmars-d-learn

On Thursday, 8 February 2018 at 21:09:33 UTC, JN wrote:

Hi,

is there any way to debug binaries on Windows? I'd at least 
like to know which line of code made it crash. If it's D code, 
I get a call trace usually, but if it's a call to a C library, 
I get a crash and that's it. I am using VSCode and I'd prefer 
to debug in it if possible, but using other IDEs is a 
possibility for me if that will help.


You can debug D programs from VS Code using the C++ plugin:

https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools

It requires some configuring, but from what I remember it was all 
very straightforward.


Re: Debugging bad requests with vibe

2018-02-09 Thread Seb via Digitalmars-d-learn
On Thursday, 8 February 2018 at 17:09:44 UTC, Nicholas Wilson 
wrote:
Is there a way I can see/log what requests are being made? I 
can change both the client and server.


-v and -vv