Re: Linkage question
On Monday, 24 January 2022 at 19:41:30 UTC, frame wrote: On Monday, 24 January 2022 at 18:30:02 UTC, Stanislav Blinov wrote: The difference is in how arguments are being passed, which you seem to have discovered already :) Would like to know where the linkage format is defined, thx. It should be here: https://dlang.org/spec/abi.html although IIRC it might not be 100% up to date. Ah, yes. Thanks. Maybe I should read it more carefully =) It claims that the D calling convention matches C. But it seems that the arguments are pushed in order whereas C does it in reverse order and the -218697648 value is indeed my 3rd string pointer. that's a bug with dmd or the spec, arguments are currently passed in reverse order compared to C on 64-bit even though they should be the same see: https://issues.dlang.org/show_bug.cgi?id=20204 https://github.com/dlang/dmd/pull/13287 https://github.com/dlang/dlang.org/pull/3120
Re: unordered output of an associated array of associated arrays
On Tue, Jan 25, 2022 at 02:46:43AM +, forkit via Digitalmars-d-learn wrote: > On Tuesday, 25 January 2022 at 02:12:50 UTC, H. S. Teoh wrote: > > > > That's the *easy* way out?? Try this instead: > > > > aaTable.keys.sort.each!((k) { > > aaTable[k].keys.sort.each!((kk) { > > writefln("%s:%s:%s", k, kk, aaTable[k][kk]); > > }); > > }); [...] > surely, this is voodoo? ;-) No, this is D-doo. We're here to do-D-doo. :-D T -- If you're not part of the solution, you're part of the precipitate.
Re: What is safe to do in an extern (C) function and how can I test this?
On Tuesday, 25 January 2022 at 01:41:03 UTC, Steven Schveighoffer wrote: On 1/24/22 8:31 PM, Jaime wrote: Can I, for instance, safely call Fiber.yield in a C callback that I know will be run in a Fiber? I would *imagine* it's fine, all the fiber context switch is doing (WRT the stack) is swapping out the fiber portion of the stack (i.e. back to the `Fiber.call` invokation), which should include the C stack portions as well. There's a lot of low-level details in the Fiber.d file itself: https://github.com/dlang/druntime/blob/e390ba7e0a1f80f15e72ca773fca7252057ba4c5/src/core/thread/fiber.d#L387 -Steve On Tuesday, 25 January 2022 at 02:02:27 UTC, H. S. Teoh wrote: I haven't tested this myself, but I *think* it should be OK. One thing to watch out for, though, is the size of the Fiber's stack (this can be specified when you first create the Fiber). If the C part of the code uses up too much stack space (e.g. if somewhere in the C code it tries to allocate a large object on the stack), you may inadvertently overflow the Fiber's stack and cause a crash or abort. Increasing the stack size of the Fiber when it is created should fix this problem. T The insight and vote of confidence are much appreciated, you two. Steven, good call to check out the implementation of Fiber, I'll do that.
Re: unordered output of an associated array of associated arrays
On Tuesday, 25 January 2022 at 02:12:50 UTC, H. S. Teoh wrote: That's the *easy* way out?? Try this instead: aaTable.keys.sort.each!((k) { aaTable[k].keys.sort.each!((kk) { writefln("%s:%s:%s", k, kk, aaTable[k][kk]); }); }); T surely, this is voodoo? ;-)
Re: unordered output of an associated array of associated arrays
On Tue, Jan 25, 2022 at 02:04:26AM +, forkit via Digitalmars-d-learn wrote: [...] > // -- > module test; > > import std; > > void main() > { > auto aaTable = > ([ >"typeB" : [ 10002 : [1, 1, 0, 0, 0, 0, 0, 0], >10001 : [1, 0, 0, 0, 0, 0, 0, 0] > ], >"typeC" : [ 10007 : [1, 1, 1, 1, 1, 1, 0, 0], >10006 : [1, 1, 1, 1, 1, 1, 0, 0] > ], >"typeA" : [ 10005 : [1, 1, 1, 1, 1, 0, 0, 0], >10003 : [1, 1, 1, 0, 0, 0, 0, 0], >10004 : [1, 1, 1, 1, 0, 0, 0, 0] > ] > ]); > > string[] orderedKeyPairSet; > > foreach (key, pair; aaTable.byPair) > { > foreach(k, p; pair.byPair) > orderedKeyPairSet ~= key ~ ":" ~ k.to!string ~ ":" ~ > p.to!string; > } > > orderedKeyPairSet.sort; > > foreach(s; orderedKeyPairSet) > writeln(s); That's the *easy* way out?? Try this instead: aaTable.keys.sort.each!((k) { aaTable[k].keys.sort.each!((kk) { writefln("%s:%s:%s", k, kk, aaTable[k][kk]); }); }); T -- Try to keep an open mind, but not so open your brain falls out. -- theboz
Re: unordered output of an associated array of associated arrays
On Tuesday, 25 January 2022 at 00:43:07 UTC, forkit wrote: oh. thanks :-) I will get that integrated into my example code, and will post again, once it's working (so others can learn too) ok.. so I took the easy way out ;-) output is now ordered: typeA:10003:[1, 1, 1, 0, 0, 0, 0, 0] typeA:10004:[1, 1, 1, 1, 0, 0, 0, 0] typeA:10005:[1, 1, 1, 1, 1, 0, 0, 0] typeB:10001:[1, 0, 0, 0, 0, 0, 0, 0] typeB:10002:[1, 1, 0, 0, 0, 0, 0, 0] typeC:10006:[1, 1, 1, 1, 1, 1, 0, 0] typeC:10007:[1, 1, 1, 1, 1, 1, 0, 0] // -- module test; import std; void main() { auto aaTable = ([ "typeB" : [ 10002 : [1, 1, 0, 0, 0, 0, 0, 0], 10001 : [1, 0, 0, 0, 0, 0, 0, 0] ], "typeC" : [ 10007 : [1, 1, 1, 1, 1, 1, 0, 0], 10006 : [1, 1, 1, 1, 1, 1, 0, 0] ], "typeA" : [ 10005 : [1, 1, 1, 1, 1, 0, 0, 0], 10003 : [1, 1, 1, 0, 0, 0, 0, 0], 10004 : [1, 1, 1, 1, 0, 0, 0, 0] ] ]); string[] orderedKeyPairSet; foreach (key, pair; aaTable.byPair) { foreach(k, p; pair.byPair) orderedKeyPairSet ~= key ~ ":" ~ k.to!string ~ ":" ~ p.to!string; } orderedKeyPairSet.sort; foreach(s; orderedKeyPairSet) writeln(s); } // ---
Re: What is safe to do in an extern (C) function and how can I test this?
On Tue, Jan 25, 2022 at 01:31:29AM +, Jaime via Digitalmars-d-learn wrote: > **The lede**: > > Can I, for instance, safely call Fiber.yield in a C callback that I > know will be run in a Fiber? > > The stack will look like: > Thread > |- Fiber in D runtime > | |- Call into a C API (stays on same thread) > | | |- Extern (C) callback (stays on same thread) > | | | |- Fiber.yield <-- Is this OK? I haven't tested this myself, but I *think* it should be OK. One thing to watch out for, though, is the size of the Fiber's stack (this can be specified when you first create the Fiber). If the C part of the code uses up too much stack space (e.g. if somewhere in the C code it tries to allocate a large object on the stack), you may inadvertently overflow the Fiber's stack and cause a crash or abort. Increasing the stack size of the Fiber when it is created should fix this problem. T -- Those who don't understand D are condemned to reinvent it, poorly. -- Daniel N
Re: What is safe to do in an extern (C) function and how can I test this?
On 1/24/22 8:31 PM, Jaime wrote: **The lede**: Can I, for instance, safely call Fiber.yield in a C callback that I know will be run in a Fiber? The stack will look like: Thread |- Fiber in D runtime | |- Call into a C API (stays on same thread) | | |- Extern (C) callback (stays on same thread) | | | |- Fiber.yield <-- Is this OK? Also, in general, is there a convenient way to know or test if particular C callbacks are safe? Or is it just case by case? **The context I was gonna bury the lede in but thought better of it**: So, I am a big lame novice. Don't worry, I know this already. I'm trying to use gtk-d, but I don't even know how to use gtk, so I'm learning them both at once. Probably not a good idea, I know. From what I can tell so far, it seems like the way gtk works is you write your whole application in terms of gtk's event loop. I really don't want to do that, so -- and I realize this is probably an even worse idea, but I don't know the right thing to do -- I decided I'd try writing a worker thread class -- "Rope" -- and run gtk's event loop in a Rope. A Rope runs its given task in a new Fiber in a new thread, and that thread repeatedly resumes the fiber and terminates when the fiber terminates, but, in the meantime, takes some time to act as an executor each time the fiber suspends, accepting work in std.concurrency messages and running it on the same thread as its main fiber. My thought was that this way, I can call gtk-d's API from any thread, and still have all the calls happen on the same thread that the event loop is running on, as the API requires. All I needed, then, was some way to make gtk-d suspend the fiber it's running on, to give its rope some time to service external work. My first thought was to use glib.Timeout.Timeout.add and put Fiber.yield in the timeout callback. The potential problem: the timeout callback, of course, has to be extern (C). Now, I could just drop the more general concept of Rope and rewrite it specifically for gtk, and drop the whole Fiber part, and instead directly put the calls to std.concurrency.receiveTimeout in the glib.Timeout.Timeout.add callback. Assuming, of course, receiveTimeout would be any safer to call from extern (C) than Fiber.yield would. But that's just the trouble, I can't guess which would be safer, and even a minimal test for this question seems daunting. I would *imagine* it's fine, all the fiber context switch is doing (WRT the stack) is swapping out the fiber portion of the stack (i.e. back to the `Fiber.call` invokation), which should include the C stack portions as well. There's a lot of low-level details in the Fiber.d file itself: https://github.com/dlang/druntime/blob/e390ba7e0a1f80f15e72ca773fca7252057ba4c5/src/core/thread/fiber.d#L387 -Steve
What is safe to do in an extern (C) function and how can I test this?
**The lede**: Can I, for instance, safely call Fiber.yield in a C callback that I know will be run in a Fiber? The stack will look like: Thread |- Fiber in D runtime | |- Call into a C API (stays on same thread) | | |- Extern (C) callback (stays on same thread) | | | |- Fiber.yield <-- Is this OK? Also, in general, is there a convenient way to know or test if particular C callbacks are safe? Or is it just case by case? **The context I was gonna bury the lede in but thought better of it**: So, I am a big lame novice. Don't worry, I know this already. I'm trying to use gtk-d, but I don't even know how to use gtk, so I'm learning them both at once. Probably not a good idea, I know. From what I can tell so far, it seems like the way gtk works is you write your whole application in terms of gtk's event loop. I really don't want to do that, so -- and I realize this is probably an even worse idea, but I don't know the right thing to do -- I decided I'd try writing a worker thread class -- "Rope" -- and run gtk's event loop in a Rope. A Rope runs its given task in a new Fiber in a new thread, and that thread repeatedly resumes the fiber and terminates when the fiber terminates, but, in the meantime, takes some time to act as an executor each time the fiber suspends, accepting work in std.concurrency messages and running it on the same thread as its main fiber. My thought was that this way, I can call gtk-d's API from any thread, and still have all the calls happen on the same thread that the event loop is running on, as the API requires. All I needed, then, was some way to make gtk-d suspend the fiber it's running on, to give its rope some time to service external work. My first thought was to use glib.Timeout.Timeout.add and put Fiber.yield in the timeout callback. The potential problem: the timeout callback, of course, has to be extern (C). Now, I could just drop the more general concept of Rope and rewrite it specifically for gtk, and drop the whole Fiber part, and instead directly put the calls to std.concurrency.receiveTimeout in the glib.Timeout.Timeout.add callback. Assuming, of course, receiveTimeout would be any safer to call from extern (C) than Fiber.yield would. But that's just the trouble, I can't guess which would be safer, and even a minimal test for this question seems daunting.
Re: unordered output of an associated array of associated arrays
On Tuesday, 25 January 2022 at 00:39:05 UTC, H. S. Teoh wrote: AA's are unordered containers. Do not rely on entries to appear in any specific order when you traverse an AA; it is implementation-dependent and may differ from OS to OS / platform to platform / sequence of operations performed on the AA since its initialization / phase of the moon. Any specific order that may appear in an AA is pure coincidence and may not appear again next time, or may only appear again at 11:59:59 Feb 29 under a blue moon. If you need entries in your AA in a specific order, extract them (or their keys) into an array then sort them yourself. E.g.: string[string] myAA; auto keys = myAA.keys; sort(keys); foreach (k; keys) { ... // now keys will be in the expected order } T oh. thanks :-) I will get that integrated into my example code, and will post again, once it's working (so others can learn too)
Re: unordered output of an associated array of associated arrays
On Tuesday, 25 January 2022 at 00:23:40 UTC, forkit wrote: another example: output is: typeA: 10001:[0, 0, 1, 1, 1, 1, 1, 1] 10002:[0, 0, 0, 1, 1, 1, 1, 1] typeB: 10005:[0, 0, 0, 0, 0, 0, 1, 1] 10003:[0, 0, 0, 0, 1, 1, 1, 1] 10004:[0, 0, 0, 0, 0, 1, 1, 1] // -- module test; import std; void main() { auto aaTable2 = ([ "typeA" : [ 10001 : [0, 0, 1, 1, 1, 1, 1, 1], 10002 : [0, 0, 0, 1, 1, 1, 1, 1] ], "typeB" : [ 10003 : [0, 0, 0, 0, 1, 1, 1, 1], 10004 : [0, 0, 0, 0, 0, 1, 1, 1], 10005 : [0, 0, 0, 0, 0, 0, 1, 1] ] ]); foreach (topLevelKey, topLevelValue; aaTable2.byPair) { writefln("%s:", topLevelKey); foreach(key, value; topLevelValue) { writefln("\t%s:%s", key, value); } } } //--
Re: unordered output of an associated array of associated arrays
On Tue, Jan 25, 2022 at 12:23:40AM +, forkit via Digitalmars-d-learn wrote: > so I'm trying to understand why the output of the code below, is in > reverse order of the declaration (and how to fix it so that it outputs > in an ordered way) AA's are unordered containers. Do not rely on entries to appear in any specific order when you traverse an AA; it is implementation-dependent and may differ from OS to OS / platform to platform / sequence of operations performed on the AA since its initialization / phase of the moon. Any specific order that may appear in an AA is pure coincidence and may not appear again next time, or may only appear again at 11:59:59 Feb 29 under a blue moon. If you need entries in your AA in a specific order, extract them (or their keys) into an array then sort them yourself. E.g.: string[string] myAA; auto keys = myAA.keys; sort(keys); foreach (k; keys) { ... // now keys will be in the expected order } T -- Freedom of speech: the whole world has no right *not* to hear my spouting off!
unordered output of an associated array of associated arrays
so I'm trying to understand why the output of the code below, is in reverse order of the declaration (and how to fix it so that it outputs in an ordered way) i.e. output is: typeA: A2:A2value A1:A1value typeB: B3:B3value B2:B2value B1:B1value // -- module test; import std; void main() { string[string][string] aaTable = ([ "typeA" : ["A1" : "A1value", "A2" : "A2value"], "typeB" : ["B1" : "B1value", "B2" : "B2value", "B3" : "B3value"] ]); foreach (topLevelKey, topLevelValue; aaTable.byPair) { writefln("%s:", topLevelKey); foreach(key, value; topLevelValue) { writefln("\t%s:%s", key, value); } } } //--
Re: How to do same as 'nmap' command from within a D program?
On Saturday, 22 January 2022 at 20:55:38 UTC, Daren Scot Wilson wrote: I'm writing a command line program to control certain hardware devices. I can hardcode or have in a config file the IP addresses for the devices, if I know that info. If I don't? Depending on the hardware, you might be able to send a broadcast packet and listen to replies too. The nmap command you do just does pings to each address in that range (btw I actually wrote a little module to turn one of those ranges into a bunch of ip address strings: https://github.com/adamdruppe/arsd/blob/master/cidr.d ). The stdlib doesn't have a convenient ping function though. But yah depending on the hardware you might be able to do udp broadcasts and such. I had this led tower light thing for a client I had to set up and that's what i did there - udp broadcast a config packet, get the list of all the mac addresses, send config packets to change their ips, and get going.
Re: How to do same as 'nmap' command from within a D program?
On Sunday, 23 January 2022 at 06:30:11 UTC, frame wrote: On Saturday, 22 January 2022 at 20:55:38 UTC, Daren Scot Wilson wrote: I don't see any D std.* libraries that do this. Are there a Dub packages I should look at? If you really want to this in D without any external app or OS API you could just ping all possible hosts, see which respond and then use `getHostByAddr()` to find the hostname. Another more professional way is to query the ARP protocol, where you send a packet as broadcast to all interfaces in the network to find a MAC for a given IP - if any host responses with a MAC, the host is up. You have to build the packet data for yourself, there are examples on the web. The socket to use is family:INET, type:RAW and protocol:ICMP for ping or RAW for ARP or anything that isn't listed in D. As you can see, it's required to test every possible IP out (except for any other discovery protocols supported by your network/router). For this reason, any OS does this scan periodically and caches the result. On UNIX you can just directly read the file `/proc/net/arp`, no need to use nmap. I'll try this. Looks more educational. This is a personal project, a show-off project. Once I'm done with another portion of it, I'll get onto this. My program will need to scan only once, not even once per run, since I can stash the results in a config file, but once whenever the user knows the hardware devices have changed.
Re: Linkage question
On Monday, 24 January 2022 at 19:41:30 UTC, frame wrote: It claims that the D calling convention matches C. But it seems that the arguments are pushed in order whereas C does it in reverse order and the -218697648 value is indeed my 3rd string pointer. Windows has two calling conventions for C functions, `cdecl` and `stdcall`. In D, `cdecl` is called `extern (C)` and `stdcall` is called `extern (Windows)`. Windows API functions use the `stdcall` convention [1], so you need to use `extern (Windows)` when calling them from D. [1] https://docs.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-170
Re: Linkage question
On Monday, 24 January 2022 at 18:30:02 UTC, Stanislav Blinov wrote: The difference is in how arguments are being passed, which you seem to have discovered already :) Would like to know where the linkage format is defined, thx. It should be here: https://dlang.org/spec/abi.html although IIRC it might not be 100% up to date. Ah, yes. Thanks. Maybe I should read it more carefully =) It claims that the D calling convention matches C. But it seems that the arguments are pushed in order whereas C does it in reverse order and the -218697648 value is indeed my 3rd string pointer.
Re: Linkage question
On Monday, 24 January 2022 at 17:23:01 UTC, frame wrote: I understand that the linkage must match but besides the name mangling, what's happen here? What is the difference if I remove the `extern (C)` part from the T alias? The difference is in how arguments are being passed, which you seem to have discovered already :) Would like to know where the linkage format is defined, thx. It should be here: https://dlang.org/spec/abi.html although IIRC it might not be 100% up to date.
Linkage question
If I declare a function as extern(C) inside a DLL, I have also to cast the function pointer as extern(C) or it fails calling, eg. ```d // --- my.dll export extern (C) void log(int mode, string a, string b, string c) { /* stuff */ } // --- main.d alias T = extern (C) void function(int, string, string, string); auto fnPtr = cast(T)GetProcAddress(/* stuff */); ``` I understand that the linkage must match but besides the name mangling, what's happen here? What is the difference if I remove the `extern (C)` part from the T alias? Doing that supplies 2nd and 3rd paramter as fine pointers but the 1st argument comes wrong (eg. 10 becomes -218697648) and the last argument is garbage too, so the D-linkage format is something different. Would like to know where the linkage format is defined, thx.
Re: dustmite and Windows file access errors
On Monday, 24 January 2022 at 17:17:28 UTC, Anonymouse wrote: Indexing is off for the parent directory. What else can I do? Disable anti-virus. If that doesn't help, you could try using Sysinternals Process Monitor to check what is accessing the file.
dustmite and Windows file access errors
This is maybe more a Windows (11) question than it is a dustmite one. Semi-OT. I'm trying to reduce https://forum.dlang.org/thread/muehtdyjabmjxosmj...@forum.dlang.org, and it's Windows so I don't know what I'm doing. After multiple attempts at piecing together a batch tester script that both checks for compiler stderr/stdout *and* the errorlevel of the process, I resigned and wrote a quick thing in D to do it instead. Off the top of my head; ```d import std; static immutable command = `ldc2.exe -flags and stuff copy/pasted from dub build -v output` .replace('\\', '/') .split(' '); int main() { immutable result = execute(command); return ((result.code == 5) && !result.output.length) ? 0 : 1; } ``` Once compiled it seems to work when called manually, and dustmite accepts it as a tester, but there are a lot of errors output to the console during actual reduction. Error while attempting to delete init.lookahead.3203: init.lookahead.3203\source\somefile.d: The process cannot access the file because it is being used by another process. Error while attempting to rename init.reduced.inprogress to init.reduced: Attempting to rename file init.reduced.inprogress to init.reduced: Access is denied. They occur *constantly*, and dustmite halts and waits a full second each time before retrying, sometimes with the same message repeated some 5 times. (Meaning access to the file was blocked for the same 5 seconds.) Indexing is off for the parent directory. What else can I do?