Re: How to use ResizerWidget in Dlangui app..?
On Monday, 30 December 2019 at 23:32:37 UTC, ShadoLight wrote: Hi, I suspect I'm missing something obvious, but ResizerWidget is not working for me on Windows - it shows the 'dragging'-cursor when hovering the mouse on the ResizerWidget, but dragging with the left mouse button does nothing. I ran into the same issue. The resizeEvent callback is not implemented yet. Below is my custom implementation. /** A completed resizer widget. As of 2016-12-30, the ResizerWidget does not work out of the box. This class implement the missing piece. */ class Resizer : ResizerWidget { /// Default initialization. this () { super (); initResizeCb (); } /// Create with ID parameter. this (string ID, Orientation orient = Orientation.Vertical) { super (ID, orient); initResizeCb (); } /// Initialize the resize on drag behaviour callback. protected void initResizeCb () { this.resizeEvent = (ResizerWidget source, ResizerEventType event, int currentPosition) { if (event != ResizerEventType.Dragging) { return; } if (_orientation == Orientation.Horizontal) { auto delta = _previousWidget.width - currentPosition; auto pw= max (0, _previousWidget.width - delta); auto mw= max (0, _nextWidget.width + delta); _previousWidget .minWidth (pw) .maxWidth (pw); _nextWidget .minWidth (mw) .maxWidth (mw); } else if (_orientation == Orientation.Vertical) { auto delta = _previousWidget.height - currentPosition; auto pw= max (0, _previousWidget.height - delta); auto mw= max (0, _nextWidget.height + delta); _previousWidget .minHeight (pw) .maxHeight (pw); _nextWidget .minHeight (mw) .maxHeight (mw); } parent.requestLayout (); }; } }
Re: Learning delegates
On Sunday, 8 September 2019 at 10:04:57 UTC, Joel wrote: I'm trying to understand delegates. Is there any good ways I can get a better understanding of them? I am no compiler implementer, so what is below may contain a lot of inaccuracies and conceptual shortcuts, but here is my view of delegates in D. I hope this helps. Delegates are fat function pointers. D arrays are also fat function pointers: they can be implemented as a struct with a size_t length and a pointer to the data: sruct DArray(T) { size_t length; T * data; } D delegates can be implemented as a pointer to some context data and a function pointer, something similar to D arrays: struct DDelegate(Context, Return, Args) { Context context; Return function(Args) functionPointer; } The context can be: - a struct value - a class instance - some data from a local function frame when the delegate is used as a closure. The compiler replaces a call to the delegate in the source code by a call to the function pointer with the right data for runtime. Something like: dg.functionPointer(dg.context, "hello, world");
Re: Pro programmer
On Monday, 26 August 2019 at 16:41:05 UTC, GreatSam4sure wrote: Thanks, is there tutorial on the translation of Java to D. Which tools is used? Pls guide me, I am really interested in translating JavaFX to D From what I can recall and find on the Internet, the tool used was named "tioport". It is only viewable on the old (deprecated) dsource.org website. Last activity was in 2007. A runtime library, dejavu, was used to emulate the java standard library. A port of swt 3.2.1 was done with it. I doubt that it supported D 2. I cannot find anything fresher than 2007 concerning tioport. The DWT project is still active: - https://code.dlang.org/packages/dwt - https://github.com/d-widget-toolkit/dwt I suppose once the first translation was made, the resulting code base was maintained incrementally, without resorting to whole translation of the SWT code.
Re: How to get name of my application (project)
On Saturday, 3 August 2019 at 09:26:03 UTC, Andrey wrote: Hello, how to get name of my application (project) that we write in dub.json? Is there any compile-time constant like __MODULE__? If I understand the question correctly, you are looking for std.file.thisExePath: - http://dpldocs.info/experimental-docs/std.file.thisExePath.html - https://dlang.org/phobos/std_file.html#thisExePath
Re: question about call cpp class constructer without new , and define cpp delegate
On Thursday, 27 June 2019 at 05:57:49 UTC, evilrat wrote: On Thursday, 27 June 2019 at 05:37:08 UTC, ChangLoong wrote: If I want call cpp class constructer without new method, is there a way to do that ? If what you really want is to actually allocate using C++ new operator from D, then that is very problematic and not portable even across compilers on same OS. If C++ side has poor design around this specific issue and expects passed object to be delete'd (using the C++ delete operator) later then you are in trouble. In that case you have to make simple wrapper on C++ side to be able to call new/delete from D. I though support for C++ allocation had improved. In a recent release, there was the addition of core.stdcpp.new, but I didn't try it out: - http://dpldocs.info/experimental-docs/core.stdcpp.new_.html - https://en.cppreference.com/w/cpp/memory/new/operator_new Are there still pitfalls to be wary of?
Re: Strange closure behaviour
On Sunday, 16 June 2019 at 01:36:38 UTC, Timon Gehr wrote: It's a bug. It's memory corruption. Different objects with overlapping lifetimes use the same memory location. Okay. Seen that way, it is clear to me why it's a bug. ... No, it's not the same. Python has no sensible notion of variable scope. >>> for i in range(3): pass ... >>> print(i) 2 Yuck. I got confused by this Python behavior: ls = [] for i in range(0, 5): ls.append(lambda x: x + i) for fun in ls: print(fun(0)) This prints: 4 4 4 4 4
Re: Strange closure behaviour
On Saturday, 15 June 2019 at 01:21:46 UTC, Emmanuelle wrote: On Saturday, 15 June 2019 at 00:30:43 UTC, Adam D. Ruppe wrote: On Saturday, 15 June 2019 at 00:24:52 UTC, Emmanuelle wrote: Is it a compiler bug? Yup, a very longstanding bug. You can work around it by wrapping it all in another layer of function which you immediately call (which is fairly common in javascript): funcs ~= ((x) => (int i) { nums[x] ~= i; })(x); Or maybe less confusingly written long form: funcs ~= (delegate(x) { return (int i) { nums[x] ~= i; }; })(x); You write a function that returns your actual function, and immediately calls it with the loop variable, which will explicitly make a copy of it. Oh, I see. Unfortunate that it's a longstanding compiler bug, but at least the rather awkward workaround will do. Thank you! I don't know if we can tell this is a compiler bug. The same behavior happens in Python. The logic being variable `x` is captured by the closure. That closure's context will contain a pointer/reference to x. Whenever x is updated outside of the closure, the context still points to the modified x. Hence the seemingly strange behavior. Adam's workaround ensures that the closure captures a temporary `x` variable on the stack: a copy will be made instead of taking a reference, since a pointer to `x` would be dangling once the `delegate(x){...}` returns. Most of the time, we want a pointer/reference to the enclosed variables in our closures. Note that C++ 17 allows one to select the capture mode: the following link lists 8 of them: https://en.cppreference.com/w/cpp/language/lambda#Lambda_capture. D offers a convenient default that works most of the time. The trade-off is having to deal with the creation of several closures referencing a variable being modified in a single scope, like the incremented `x` of the for loop. That said, I wouldn't mind having the compiler dealing with that case: detecting that `x` is within a for loop and making copies of it in the closures contexts.
Re: need article: How is working D-GC?
On Tuesday, 11 June 2019 at 18:20:59 UTC, KnightMare wrote: please write some explanation about subj. - what exactly it scans? - why it scan data-segment? https://issues.dlang.org/show_bug.cgi?id=15723 https://issues.dlang.org/show_bug.cgi?id=19947 precise GC doesn't help with issues. - maybe add new type like gcpointer or something (making word "pointer" as keyword is not good idea) that must be scanned 100%. some mix of uint/ulong and void* with arithmetic support +=N -=N for bytes offset without any cast. not for @safe. - maybe to make precise gc as option for compiler (not runtime) that will scans only pointer vars, gcpointer and other roots, not the all data segment (no longs, no doubles[5], no long/double fields in structs etc)? at runtime GC has no info about data-segment so its pessimistic and scans all of it (probably. need clarifying article). if make it compile option than compiler/linker can say exactly what should be scanned and what shouldn't. - when I transfer some gcptr to C or another library its only my responsibility to invoke GC.addRoot/addRange or some .holdThisData in case addRoot/addRange has another mean. the point is "dont scan everything, scan what user/compiler point to u". GC is dangerous for now, it should be fixed, nobody will work with such GC at critical/24/7 systems. imo pessimistic gc should be removed at all. in case GC won't be fixed tell us, it will be fair. Mike Parker has written a series of articles explaining the D GC: https://dlang.org/blog/the-gc-series/ It talks about: - its basic operations, - how to measure its usage and profile a D program for allocations, - various strategies to manage memory like the stack and C's malloc/free functions. At D Conf 2019, Walter Bright made his keynote presentation about memory allocation strategies, going beyond the GC: - video: https://www.youtube.com/watch?v=_PB6Hdi4R7M - slides: https://dconf.org/2019/talks/bright.pdf If I recall correctly, there is (or was) also a precise GC in the work, but I currently don't have any links to it.
Re: Reading Dicom files in Dlang
On Monday, 3 June 2019 at 14:19:40 UTC, Rnd wrote: On Friday, 31 May 2019 at 16:43:28 UTC, rnd wrote: On Friday, 31 May 2019 at 13:49:02 UTC, KnightMare wrote: struct Range { private __vector(ushort) _outer; private size_t _a, _b; this(vector(ushort) data, size_t a, size_t b) { // line 457 _outer = data; _a = a; _b = b; } imo problem is in string private __vector(ushort)_outer; it looks like template(vector!ushort) or function or this is vector from core.simd and replacing it to private long _outer; fix the problem paste code imebra.d and imebra_im.d to someplace Best to download it from https://imebra.com/get-it/ so that all files are available to you. I am still waiting for someone to help me with this. Can we directly call C functions from D without going through swig? We can call C functions directly from D. First, the functions must be declared in D, as D's syntax is different from C's. There exists tools to help us with that : - dstep, https://code.dlang.org/packages/dstep - dpp, https://code.dlang.org/packages/dpp The latter, dpp, acts like a preprocessor to allow inclusion with `#include` as would be done with C header files. The swig D module is quite old and I would presume it is outdated - but I may be wrong. Note that the standard C library is available in the `core.stdc` modules. Sometimes, these tools manage to translate 95% of header files properly, but some manual tweaking is necessary to handle the remaining 5%. The following page in the D documentation explains how to interface with C: https://dlang.org/spec/interfaceToC.html . Looking at the output generally gives a good inspiration of what code pattern to use to fix the issues. C++ is a different matter. The binding tool ecosystem gives more mixed results than with C: - dstep does not generate declarations for C++; - dpp is still a work in progress; the last time I looked at its commits, I saw some unit tests checking the binding of simple classes - but I wouldn't expect it to work with much of the STL; - There exist Binderoo: https://github.com/GooberMan/binderoo which is a mean to script C++ game using D, less active than the first two, but could be helpful, I haven't researched it much. The author gave a presentation during DConf 2017: https://www.youtube.com/watch?v=2B0-jukh4TU . The following page of the D documentation explains how to interface with C++: https://dlang.org/spec/cpp_interface.html . Interfacing with C is much easier than with C++. I was once in need of a C++ library without any C API; I wrote a wrapper for it: - some C++ function within an `extern "C" {}` declaration, - with helper function to create and delete my C++ class instances, - the main C++ methods I wanted to expose, - a D binding declaration, exposing the previous function to D, - a higher level D mirroring the C++ classes, - exception were caught in the C++ `extern "C" {}` function: I returned a special Result struct containing a boolean status, the result or null, and a possible error message. I would then throw a D exception to let the user code handle the error. Nowadays, D's C++ support is better. If you can restrict to just a subset of the library, writing a wrapper might be feasible, but would include wrapping part of the STL not yet in the `core.stdcpp` modules (for libraries using the STL).
Re: Why is creating of if Expressions not allowed?
On Sunday, 24 March 2019 at 16:18:49 UTC, sighoya wrote: Why auto GenIf()() { return mixin("if(true) { return true;} else {return false;}"); } public bool testFunction2() { GenIf!(); } gives me: onlineapp.d-mixin-3(3): Error: expression expected, not if onlineapp.d(8): Error: template instance `onlineapp.GenIf!()` error instantiating Because D uses if statements, no if expressions. The equivalent of an if expression is the ternary operator: bool-condition ? if-true : if-false;
Re: Is there any way for non-blocking IO with phobos?
On Tuesday, 13 November 2018 at 13:52:57 UTC, Sobaya wrote: I want to connect to a server and communicate with ssh. So I tried to spawn the process of ssh using pipeProcess function, and read/write with its pipe's stdin and stdout. But I don't know how many lines are sent from the server for an input, so readln function blocks. I think this can be solved with non-blocking IO, but I cannot find how do I use non-blocking IO with phobos. Please give me any ideas. Thanks. I had some success with the "hasdata" package available on code.dlang.org: https://code.dlang.org/packages/hasdata Below is a sample program that I have tested on Linux: -- /+ dub.sdl: name "non-blocking-io" description "A non blocking IO example using hasdata." authors "Rémy J. A. Mouëza" license "MIT" dependency "hasdata" version="~>1.1.0" -- sourcePaths "." configuration "application" { targetType "executable" } +/ // Written in the D programming language: http://dlang.org import std.process; import std.string; import std.range; import std.stdio; import core.thread; import hasdata; struct NonBlockingPs { /// The underlying vlc process. ProcessPipes ps; alias ps this; immutable bufsize = 8; this (string [] args...) { this.ps = pipeProcess (args, Redirect.stdin | Redirect.stdout | Redirect.stderrToStdout); } ~this () { if (! ps.pid.tryWait.terminated) { ps.pid.kill (); } } string [] readlines () { string lines; string line; char [bufsize] buffer; try { int loop = 16; while (loop -- > 0 && ps.stdout.hasData) { line = cast (string) ps.stdout.rawRead (buffer); if (! line.empty) { lines ~= line; } } } catch (Exception e) { "Exception: %s".writeln (e); } return lines.splitLines (); } } void main () { NonBlockingPs ps = NonBlockingPs ("bash", "-c", ` for i in {1..10}; do printf "hello %02d" $i sleep 1 done `); while (! ps.pid.tryWait.terminated) { string [] text = ps.readlines (); if (text.empty) { "Nothing to read for now".writeln; } else { "=> %s".writefln (text.join ("\n => ")); } Thread.getThis ().sleep (500.dur!"msecs"); } } -- And here is the output of its execution (launched with `dub nbio.d` -- as I named the file `nbio.d`): Nothing to read for now => hello 01 Nothing to read for now => hello 02 Nothing to read for now => hello 03 Nothing to read for now => hello 04 Nothing to read for now => hello 05 Nothing to read for now => hello 06 Nothing to read for now => hello 07 Nothing to read for now => hello 08 Nothing to read for now => hello 09 Nothing to read for now => hello 10 Nothing to read for now
Re: Fast GC allocation of many small objects
On Saturday, 31 March 2018 at 09:10:13 UTC, Boris-Barboris wrote: On Friday, 30 March 2018 at 20:31:35 UTC, Per Nordlöw wrote: Is there a faster way of allocating many small class objects such as... maybe something like this: import std.conv: to; import std.stdio; class Node {} class StrNode : Node { string value; } void main() { writeln(StrNode.classinfo.name);// onlineapp.StrNode size_t il = StrNode.classinfo.m_init.length; writeln(il); // 32 void[] backBuf = new void[il * 1000]; StrNode[] nodes = new StrNode[1000]; for (int i = 0; i < 1000; i++) { backBuf[i * il .. (i+1) * il] = StrNode.classinfo.m_init; nodes[i] = cast(StrNode) &backBuf[i * il]; nodes[i].value = i.to!string; } foreach (n; nodes[995..$]) writeln(n.classinfo.name, " ", n.value); // prints onlineapp.StrNode 995-999 } I would have used std.conv.emplace: import std.stdio; import std.conv : emplace, to; class Node { string value; this (long n) { this.value = n.to!string; } override string toString () { return "Node (value: " ~ value ~ ")"; } } void main (string [] args) { /* size_t size = Node.sizeof; */ size_t size = Node.classinfo.m_init.length; void [] memory = new void [size * 1000]; Node [] nodes = new Node [1000]; foreach (i, node; nodes) { void [] buf = memory [i * size.. i * size + size]; nodes [i] = emplace!Node (buf, i); } nodes [0] .writeln; nodes [$-1].writeln; }
Re: how to catch D Throwables (or exceptions) from C++?
On Thursday, 1 December 2016 at 01:58:13 UTC, Timothee Cour wrote: eg: ``` dlib.d: extern(C) void dfun(){assert(0, "some_msg");} clib.cpp: extern "C" void dfun(); void fun(){ try{ dfun(); } catch(...){ // works but how do i get "some_msg" thrown from D? } } ``` I had the a similar problem when writing bindings to the RtMidi library back in 2013. I opted for catching C++ exceptions in C++, wrap the functions in a C API; the C API returns a special type that contains a status, a result and an error message. On the D side, when a status is false, a D exception is raised, mirroring the one that was caught in C++. This strategy is described in dconf 2014: https://www.youtube.com/watch?v=1JZNvKhA3mA&t=20m45s It should be working the other way arround: catch a D exception in D, return a wrapped value: on the C++ side, if the wrapped value status is false, throw an exception Below is an sample of the code I wrote: In C++: ``` * Special return type. * - success is true when a call went right, * is false when an exception occured. * - errMsg can be used to throw a D exception. * - value is the value to be returned from a call. */ template struct answer { int success; T value; const char * errMsg; }; * Predefined types of return for RtMidi. */ typedef answer answerRtMidiIn_p; typedef answer answerRtMidiOut_p; typedef answer answerBool; typedef answer answerConstChar_p; typedef answer answerDouble; answerRtMidiIn_p RtMidiIn_new ( int api, char * clientName, unsigned int queueSizeLimit) { RtMidiIn * ptr; try { const std::string name = std::string (clientName); ptr = new RtMidiIn ((RtMidi::Api) api, name, queueSizeLimit); answerRtMidiIn_p ans = {true, ptr, ""}; return ans; } catch (RtError & error) { answerRtMidiIn_p ans = {false, 0, error.getMessage ().c_str ()}; return ans; } } ``` in D: ``` /* Special return type. * - success is true when a call went right, * is false when an exception occured. * - errMsg can be used to throw a D exception. * - value is the value to be returned from a call. */ struct answer (T) { int success; T value; const (char) * errMsg; } extern (C) { // ... answer!(void *) RtMidiIn_new ( int api, immutable(char) * clientName, uint queueSizeLimit); // ... } class RtMidiIn { // Pointer to the C++ class, package visibility. protected void * ptr; public: this ( int api = UNSPECIFIED, string clientName = "RtMidi Input Client", uint queueSizeLimit = 100) { answer!(void *) ans = RtMidiIn_new (api, clientName.toStringz, queueSizeLimit); if (! ans.success) throw new RtError (ans.errMsg.to!string); this.ptr = ans.value; } // ... } ```
Re: Tango Problems..
I suggest to try linking with both phobos and tango. Only the druntime functions contained in phobos should be used by the linker (if I am correct). Otherwise, did you take a look at code.dlang.org? Depending on your needs, there might be a dub package you could use to fill in for the missing Tango functionalites. On 08/31/2014 11:42 PM, seany wrote: On Sunday, 31 August 2014 at 21:40:51 UTC, seany wrote: On the other hand, phobos works. But I want some tango functionality, without having to hack it all by hand ...
Re: Tango Problems..
In case you don't find any druntime library, try to see if the missing symbol is in the libphobos2.a file (you'll first have to identify the directory where phobos is located): $ nm libphobos2.a | ddemangle | grep stdc | grep va_end T nothrow void core.stdc.stdarg.va_end(char*) If you get a similar result, your next step will be to try compiling your program with phobos. On 08/31/2014 11:09 PM, Rémy Mouëza wrote: Have you tried something like this: find /lib /usr/lib* /usr/local/lib* -name \*.a | grep -i druntime or a simple: locate druntime ? On 08/31/2014 10:50 PM, seany wrote: On Sunday, 31 August 2014 at 20:40:06 UTC, Rémy Mouëza wrote: -L-L/path/to/ldc/lib/ -L-Ldruntime-ldc . there is no /path/to/ldc/lib in my system - i have an /etc/ldc.conf and a /usr/bin/ldc2
Re: Tango Problems..
Have you tried something like this: find /lib /usr/lib* /usr/local/lib* -name \*.a | grep -i druntime or a simple: locate druntime ? On 08/31/2014 10:50 PM, seany wrote: On Sunday, 31 August 2014 at 20:40:06 UTC, Rémy Mouëza wrote: -L-L/path/to/ldc/lib/ -L-Ldruntime-ldc . there is no /path/to/ldc/lib in my system - i have an /etc/ldc.conf and a /usr/bin/ldc2
Re: Tango Problems..
I have checked my ldc installation: the druntime library is located in ldc2-0.12.0-linux-x86/x86/libdruntime-ldc.a You should also add a some extra flags like: -L-L/path/to/ldc/lib/ -L-Ldruntime-ldc . On 08/31/2014 05:52 PM, seany wrote: I am linking against tango ldc -I/path/to/tango -L-L/path/to/tango -L-ltango-dmd \
Re: Tango Problems..
From what I understand in the error message, the linker cannot find a druntime function: void core.stdc.stdarg.va_end(void*). I would advise to check that the druntime lib is in the import path. In your the dmd repository, you should have a dmd.conf file containing something like: [Environment64] DFLAGS=-I%@P%/../src/phobos -I%@P%/../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic (%@P% means the compiler path). This should help you to fix your command line adding for instance: -I/usr/local/lib/dmd/druntime/ In my dmd installation (2.066.0), the druntime is contained in libphobos.a/libphobos.so. Are you linking with libphobos? On 08/31/2014 03:53 PM, seany wrote: I have several files, which I am trying to import as modules to a central file. However, whyile trying to complie with dmd -L-ltango-dmd However, I am getting this error : /usr/lib/libtango-dmd.a(tango-io-Stdout-release.o): In function `_D5tango2io6stream6Format20__T12FormatOutputTaZ12FormatOutput6formatMFxAaYC5tango2io6stream6Format20__T12FormatOutputTaZ12FormatOutput': ./tango/io/Stdout.d:(.text._D5tango2io6stream6Format20__T12FormatOutputTaZ12FormatOutput6formatMFxAaYC5tango2io6stream6Format20__T12FormatOutputTaZ12FormatOutput+0x12b): undefined reference to `_D4core4stdc6stdarg6va_endFPvZv' /usr/lib/libtango-dmd.a(tango-io-Stdout-release.o): In function `_D5tango2io6stream6Format20__T12FormatOutputTaZ12FormatOutput8formatlnMFxAaYC5tango2io6stream6Format20__T12FormatOutputTaZ12FormatOutput': ./tango/io/Stdout.d:(.text._D5tango2io6stream6Format20__T12FormatOutputTaZ12FormatOutput8formatlnMFxAaYC5tango2io6stream6Format20__T12FormatOutputTaZ12FormatOutput+0x130): undefined reference to `_D4core4stdc6stdarg6va_endFPvZv' /usr/lib/libtango-dmd.a(tango-io-Stdout-release.o): In function `_D5tango2io6stream6Format20__T12FormatOutputTaZ12FormatOutput5printMFYC5tango2io6stream6Format20__T12FormatOutputTaZ12FormatOutput': ./tango/io/Stdout.d:(.text._D5tango2io6stream6Format20__T12FormatOutputTaZ12FormatOutput5printMFYC5tango2io6stream6Format20__T12FormatOutputTaZ12FormatOutput+0x131): undefined reference to `_D4core4stdc6stdarg6va_endFPvZv' /usr/lib/libtango-dmd.a(tango-io-Stdout-release.o): In function `_D5tango4text7convert6Layout13__T6LayoutTaZ6Layout6sprintMFAaAxaYAa': ./tango/io/Stdout.d:(.text._D5tango4text7convert6Layout13__T6LayoutTaZ6Layout6sprintMFAaAxaYAa+0x125): undefined reference to `_D4core4stdc6stdarg6va_endFPvZv' /usr/lib/libtango-dmd.a(tango-io-Stdout-release.o): In function `_D5tango4text7convert6Layout13__T6LayoutTaZ6Layout7convertMFAxaYAa': ./tango/io/Stdout.d:(.text._D5tango4text7convert6Layout13__T6LayoutTaZ6Layout7convertMFAxaYAa+0x11e): undefined reference to `_D4core4stdc6stdarg6va_endFPvZv' /usr/lib/libtango-dmd.a(tango-io-Stdout-release.o):./tango/io/Stdout.d:(.text._D5tango4text7convert6Layout13__T6LayoutTaZ6Layout7convertMFDFAxaZmAxaYk+0x114): more undefined references to `_D4core4stdc6stdarg6va_endFPvZv' follow I tried a small hellow owrld file, the same problem. Yes, the 64 bit linux system updated today, and since then, this is a problem - how do I start to look for cause and solve?
Re: extern (c++) std::function?
You'll certainly have to make a C++ wrapper. However, a delegate being implemented as a struct containing a context pointer and a function, you can get some degree of interoperability between C++ and D (BUT note that it is an undocumented implementation detail subject to change without notice -- althought it hasn't changed in many years): /* === */ /// ddg.d import std.stdio; import std.string; /// A C++ function that will take a D delegate. extern (C) void callDg (immutable(char)* delegate (int, int)); /// A dummy class. class X { /// This method can be used as a delegate. extern (C) immutable(char)* callMe (int i, int j) { return "%d, %d".format (i, j).toStringz; } } void main () { auto x = new X; callDg (&x.callMe); } /* === */ /// cpp_dg.cpp #include using namespace std; /// A D delegate representation in C++. struct Dg { /// The context pointer. void * ctx; /// The function within the delegate: the first argument is the context pointer. const char *(*dg) (void * ctx, int i, int j); /// C++ sugar: calling a struct Dg as a function. const char * operator ()(int i, int j) { return dg (ctx, i, j); } }; /// Extern C allows D compatibilty. extern "C" { void callDg (Dg dg) { /// Call the extern (C) D delegate. cout << dg (42, 7) << endl; } } /* === */ $ g++ -c cpp_dg.cpp $ dmd ddg.d cpp_dg.o -L-lstdc++ $ ./ddg 42, 7 /* === */ According to http://en.cppreference.com/w/cpp/utility/functional/function: " > Class template std::function is a general-purpose polymorphic > function wrapper. Instances of std::function can store, copy, and > invoke any Callable target -- functions, lambda expressions, bind > expressions, or other function objects, as well as pointers to member > functions and pointers to data members. " Thus the struct Dg in the example above should be compatible with the Botan constructors. Also, extern (C) delegates are not that convenient in D, especially with assignments of anonymous/inline ones. You may want to add a layer of abstraction to the API you expose in D so that user D delegates are used from a second extern (C) delegate itself used by the C++ wrapper: class BotanStuff { protected void delegate (string) ddg; protected BotanWrapper wrapr; this (void delegate (string) dg) { ddg = dg; wrapr = new BotanWrapper (& this.cppDg); } extern (C) void cppDg (immutable(char)* cStr) { import std.conv; dg (cStr.to!string); } } If you are planning to use Swig for your binding, this kind of wrapping may be conveniently done using custom typemaps. On 08/15/2014 05:10 AM, Etienne Cimon wrote: I'm looking into making a binding for the C++ API called Botan, and the constructors in it take a std::function. I'm wondering if there's a D equivalent for this binding to work out, or if I have to make a C++ wrapper as well?
Re: Capture parameter identifier name in a template?
I have just checked it and yes, it works with a constant that is not an enum: `const int FOO` defined in the module namespace or `static int BAR` defined in the dummy Vm class. On 08/14/2014 02:08 PM, Maxime Chevalier-Boisvert wrote: > Thanks. Does it also work with a constant that's not an enum, e.g.: const int FOO? > > On 08/14/2014 01:23 PM, Rémy Mouëza wrote: >> Using __traits (identifier, ...) and a template alias seems to work for me: >> >> import std.stdio; >> >> /// Two kinds of enums: >> >> /// A named enum. >> enum VmParams { >> OBJ_MIN_CAP, >> PROTO_SLOT_IDX, >> FPTR_SLOT_IDX, >> } >> >> /// An anonymous one. >> enum { >> ATTR_CONFIGURABLE = 3, >> ATTR_WRITABLE, >> ATTR_ENUMERABLE, >> ATTR_DELETED, >> ATTR_GETSET, >> ATTR_DEFAULT >> } >> >> /// A dummy Vm class for example purpose. >> class Vm { >> /// Stores values. >> int [string] table; >> >> /// The "classic" runtime const API. >> void defRTConst (string id, int val) { >> table [id] = val; >> } >> >> /// Using an alias with the identifier trait. >> void rtConst (alias p) () { >> table [__traits (identifier, p)] = p; >> } >> >> /// Initializes our .table member. >> this () { >> /// Using the allMembers traits we can process all the members >> of a >> /// named enum. >> foreach (member; __traits (allMembers, VmParams)) { >> int value = mixin ("VmParams." ~ member); >> this.defRTConst (member, value); >> } >> >> /// Without duplicating the name and its value. >> rtConst!ATTR_CONFIGURABLE; >> rtConst!ATTR_WRITABLE; >> rtConst!ATTR_ENUMERABLE; >> rtConst!ATTR_DELETED; >> rtConst!ATTR_GETSET; >> rtConst!ATTR_DEFAULT; >> >> /* rtConst won't work with local variables: >> // auto foo = ATTR_DEFAULT; >> // rtConst!foo; >> The code above raises a compiler error: >> Error: template instance rtConst!(foo) cannot use local >> 'foo' as parameter to non-global template rtConst(alias p)() >> */ >> } >> } >> >> void main () { >> Vm vm = new Vm; >> vm.table.writeln; >> >> /// output: >> /// ["OBJ_MIN_CAP":0, "ATTR_WRITABLE":4, "ATTR_ENUMERABLE":5, >> "ATTR_GETSET":7, "PROTO_SLOT_IDX":1, "FPTR_SLOT_IDX":2, >> "ATTR_CONFIGURABLE":3, "ATTR_DELETED":6, "ATTR_DEFAULT":8] >> } >> >> >> On 08/12/2014 07:36 PM, Maxime Chevalier-Boisvert wrote: >>> In my JavaScript VM, I have a function whose purpose is to expose D/host >>> constants to the JavaScript runtime code running inside the VM. This >>> makes for somewhat redundant code, as follows: >>> >>> vm.defRTConst("OBJ_MIN_CAP"w, OBJ_MIN_CAP); >>> vm.defRTConst("PROTO_SLOT_IDX"w, PROTO_SLOT_IDX); >>> vm.defRTConst("FPTR_SLOT_IDX"w, FPTR_SLOT_IDX); >>> vm.defRTConst("ATTR_CONFIGURABLE"w , ATTR_CONFIGURABLE); >>> vm.defRTConst("ATTR_WRITABLE"w , ATTR_WRITABLE); >>> vm.defRTConst("ATTR_ENUMERABLE"w, ATTR_ENUMERABLE); >>> vm.defRTConst("ATTR_DELETED"w , ATTR_DELETED); >>> vm.defRTConst("ATTR_GETSET"w, ATTR_GETSET); >>> vm.defRTConst("ATTR_DEFAULT"w , ATTR_DEFAULT); >>> >>> I'm just wondering if there's a way to template defRTConst so that the >>> name of an identifier I'm passing (e.g.: ATTR_DEFAULT) can be captured >>> by the template, making it so that I don't also need to pass the name as >>> a string. I expect the answer to be no, but maybe someone with more >>> knowledge of D template magic knows better. >>
Re: Capture parameter identifier name in a template?
Using __traits (identifier, ...) and a template alias seems to work for me: import std.stdio; /// Two kinds of enums: /// A named enum. enum VmParams { OBJ_MIN_CAP, PROTO_SLOT_IDX, FPTR_SLOT_IDX, } /// An anonymous one. enum { ATTR_CONFIGURABLE = 3, ATTR_WRITABLE, ATTR_ENUMERABLE, ATTR_DELETED, ATTR_GETSET, ATTR_DEFAULT } /// A dummy Vm class for example purpose. class Vm { /// Stores values. int [string] table; /// The "classic" runtime const API. void defRTConst (string id, int val) { table [id] = val; } /// Using an alias with the identifier trait. void rtConst (alias p) () { table [__traits (identifier, p)] = p; } /// Initializes our .table member. this () { /// Using the allMembers traits we can process all the members of a /// named enum. foreach (member; __traits (allMembers, VmParams)) { int value = mixin ("VmParams." ~ member); this.defRTConst (member, value); } /// Without duplicating the name and its value. rtConst!ATTR_CONFIGURABLE; rtConst!ATTR_WRITABLE; rtConst!ATTR_ENUMERABLE; rtConst!ATTR_DELETED; rtConst!ATTR_GETSET; rtConst!ATTR_DEFAULT; /* rtConst won't work with local variables: // auto foo = ATTR_DEFAULT; // rtConst!foo; The code above raises a compiler error: Error: template instance rtConst!(foo) cannot use local 'foo' as parameter to non-global template rtConst(alias p)() */ } } void main () { Vm vm = new Vm; vm.table.writeln; /// output: /// ["OBJ_MIN_CAP":0, "ATTR_WRITABLE":4, "ATTR_ENUMERABLE":5, "ATTR_GETSET":7, "PROTO_SLOT_IDX":1, "FPTR_SLOT_IDX":2, "ATTR_CONFIGURABLE":3, "ATTR_DELETED":6, "ATTR_DEFAULT":8] } On 08/12/2014 07:36 PM, Maxime Chevalier-Boisvert wrote: In my JavaScript VM, I have a function whose purpose is to expose D/host constants to the JavaScript runtime code running inside the VM. This makes for somewhat redundant code, as follows: vm.defRTConst("OBJ_MIN_CAP"w, OBJ_MIN_CAP); vm.defRTConst("PROTO_SLOT_IDX"w, PROTO_SLOT_IDX); vm.defRTConst("FPTR_SLOT_IDX"w, FPTR_SLOT_IDX); vm.defRTConst("ATTR_CONFIGURABLE"w , ATTR_CONFIGURABLE); vm.defRTConst("ATTR_WRITABLE"w , ATTR_WRITABLE); vm.defRTConst("ATTR_ENUMERABLE"w, ATTR_ENUMERABLE); vm.defRTConst("ATTR_DELETED"w , ATTR_DELETED); vm.defRTConst("ATTR_GETSET"w, ATTR_GETSET); vm.defRTConst("ATTR_DEFAULT"w , ATTR_DEFAULT); I'm just wondering if there's a way to template defRTConst so that the name of an identifier I'm passing (e.g.: ATTR_DEFAULT) can be captured by the template, making it so that I don't also need to pass the name as a string. I expect the answer to be no, but maybe someone with more knowledge of D template magic knows better.
Re: Creating Libraries Callable from C
It is possible to write a D library useable from C. However, we may not be able to hide the fact that the library has been written in D. You must first export some D function you want to use from C, using extern (C) declaration. Then declare them in your C program or headers. You will also have to declare 2 function for initializing and terminating D's runtime: char rt_init(long long); char rt_term(long long); call rt_init(0) before using your D functions (this will initialize D runtime - the D GC amongst other things), then use rt_term(0) at the end of the program - you may want to register an exit function with atexit(). With older versions of DMD we had also to create a D module with an empty main() function that had to be linked with the C program to force the D compiler to generate some symbols that were not generated within the object files. As of dmd 2.064, this is no longer necessary. Below is an example I once retrieve from this newsgroup: dlibrary.d == import std.stdio, std.array, std.range; extern(C) void printf(in char*,...); extern(C) void funcD(){ printf("C's printf in D\n"); writeln("D's writeln"); writeln("D's array alloc: ", new double[3]); writeln("D's iota: ", iota(0, 30, 4)); } cmain.c === int printf(char*, ...); void funcC() { printf("C's printf in C\n"); } char rt_init(long long); char rt_term(long long); void main(){ // code without D funcC(); rt_init(0); // initialize D's runtime //code with D funcD(); rt_term(0); // terminate D's runtime //code without D } Compilation === Compiling the D library --- dmd -c dlibrary.d Compiling the C executable -- You can do it with either dmd or gcc gcc -o cmain cmain.c dlibrary.o \ -m32 -lrt -lphobos2 -lpthread -lm \ -Xlinker -L$DMD/linux/lib32 \ -Xlinker --no-warn-search-mismatch \ -Xlinker --export-dynamic To get the proper gcc flags, use dmd in verbose mode: - first compile cmain: gcc -c cmain.c - then: dmd -v cmain.o dlibrary.o Executing - ./cmain C's printf in C C's printf in D D's writeln D's array alloc: [nan, nan, nan] D's iota: [0, 4, 8, 12, 16, 20, 24, 28] D from other programming languages == There is a project to write python extensions in D PYD: https://bitbucket.org/ariovistus/pyd I also wrote about my experiment of using Swig for a proof of concept PHP extension in D: http://forum.dlang.org/post/gwqstgaiivknieyqf...@forum.dlang.org What works for PHP can work for the other Swig supported languages (Java, C#, Go, Perl, Ruby...). On 04/26/2014 07:13 PM, TJB wrote: Is it possible to write a library that is callable from C without the enduser even knowing it was written in D? That is, can a C programmer use the library as though it were written in C straightforwardly? Or for that matter, by an enduser programming in Python or Lua where the library is being exposed through those languages' C API? I'm sure this is a widely discussed and well understood topic, but I am a newbie (and have no formal training in CS) and don't know where to look for documentation. A little baby tutorial would be super helpful and well received by this newbie. Thanks so much! TJB