Re: Why is the following failing?
On Thursday, 25 January 2024 at 15:20:01 UTC, ryuukk_ wrote: ```D void main() { char[32] id = 0; const(char)* str = "hello"; id = str[0 .. 6]; } ``` it should be a simple memcpy, why DMD complain? ``onlineapp.d(6): Error: mismatched array lengths 32 and 6 for assignment `id[] = str[0..6]``` I'm too tired to notice something obvious? You need to slice your `id` variable to be the required size. You're trying to assign the complete `id` variable to a slice of size 6. i.e: that should be used instead `id[0..6] = str[0..6]`
Re: D is a great language, but I've had a bad experience getting started
On Thursday, 14 December 2023 at 12:30:35 UTC, Renato wrote: Hi, I have been trying D for the last few days... I am only writing because I really, really like the language! It's absolutely stunning how the features it has are simple, well designed and at the same time incredibly advanced! All with an extremely fast compiler, which is almost unbelievable. Yeah, D has a really bad experience in MacOS. If you want to use it on mac, I suggest using LDC. And the package managers doesn't do D justice. You want to get the zip and setup the environment variables yourself, this is the best way to make it work. The "D recommended way" to install is by using the install.sh script, found at https://dlang.org/install.html I personally never used GDC since I develop on Windows 99% of the time (the other time is only used on the other platforms when I need to develop specific things for them). The error you're seeing is related to a DC variable. The D Compiler variable. I would guess this is a problem caused by your package manager when installing D. I've been developing a game engine which does compiler execution for the user because it can get quite hard to understand depending on the size of the project.
Re: D: How would one make a shared dynamically linked D library?
On Wednesday, 8 November 2023 at 11:48:58 UTC, BoQsc wrote: I would like to export some functionality as external shared dynamically linked D library. Is it possible to do that in D Language and what are limitations? A simple `writeln` example would be great. What I expect is an executable that uses functions, variables, classes, modules from compiled external shared D dynamic library. Example of shared dynamic libraries depending on other shared dynamic libraries would be great as well. For a complete reference, check: https://wiki.dlang.org/Win32_DLLs_in_D Create a dub project. Set its targetType to `dynamicLibrary`. Now, create a function: ```d module dllmodule; version(Windows) { import core.sys.windows.dll; mixin SimpleDllMain; } export extern(C) void helloWorld() { import std.stdio; writeln("DLL: Hello World"); } ``` Now, when you enter `dub`, you'll get a .dll on windows, and a .so on linux. You can use any compiler of your preference. Now, whenever you need to load this dll, you'll need to call: ```d module my_app; extern(C) void function helloWorld(); void main() { import core.runtime; void* dllmodule = Runtime.loadLibrary("dllmodule.dll"); version(Windows) { import core.sys.windows.dll; helloWorld = cast(typeof(helloWorld))GetProcAddress(dllmodule, "helloWorld"); } else version(Posix) { import core.sys.posix.dlfcn; helloWorld = cast(typeof(helloWorld))dlsym(dllmodule, "helloWorld"); } helloWorld(); } ``` With that, there it is. You also may need to call `core.runtime.rt_init()` if you're not calling from D
Re: druntime homebrew: setup and compile a single project with its own stdlib
On Saturday, 28 October 2023 at 18:37:37 UTC, Dmitry Ponyatov wrote: I want to play with reimplementing some tiny set of standard D library, mostly for language learning, and need some advice - is it possible to use `dub` both for building custom druntime and test app? - or I must write some batch or Makefile and call `dmd` compiler directly onto every file? - what `dmd`/`dub` command line options forces it to drop system-wide druntime/phobos and use custom local .so / .a library in place of it? - is it possible to use `dub` both for building custom druntime and test app? Yes, my engine does that what `dmd`/`dub` command line options forces it to drop system-wide druntime/phobos and use custom local .so / .a library in place of it? If you have a module source file with the same name you want to replace, the build will prioritize your own version.
Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?
On Monday, 9 October 2023 at 18:25:15 UTC, rempas wrote: On Monday, 9 October 2023 at 17:42:48 UTC, Imperatorn wrote: You could just add your own int to string I guess? That will be a good idea! I'll do it in the future if that is the case, as it's not important, and I want to finish my job. Thank you and have a great day! My engine has its own implementation of toString(long), which does not have dependency with the C runtime: https://github.com/MrcSnm/HipremeEngine/blob/master/modules/util/source/hip/util/conv.d#L180C1-L208C2 I have reimplemented the entire conv module since it is one of mostly used module and it pulled down a lot of things, so, with my util module I was able to make my program much smaller too.
Re: malloc error when trying to assign the returned pointer to a struct field
On Friday, 8 September 2023 at 07:59:37 UTC, rempas wrote: I do have the following struct: ```d struct Vec(T) { private: T* _ptr = null; // The pointer to the data u64 _cap = 0; // Total amount of elements (not bytes) we can store public: /* Create a vector by just allocating memory for it. The null terminator is not set for strings as, the vector is considered empty and we should first push something to it in order to use it! */ this(i64 size) { this._len = 0; this._cap = size; static if (is(T == char)) { size += 1; } // Additional space for the null terminator this._ptr = cast(T*)malloc(size); } } ``` That's some minimal code that I do have just to showcase it. So, some times, this work will works, some others, it will give me the following error: `Fatal glibc error: malloc.c:2594 (sysmalloc): assertion failed: (old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)` The problem seems to happen when the pointer that is returned from `malloc` is assigned to the `_ptr` field. If I just assign it to a variable and don't assign anything to `_ptr`, it will work! Is there any possible that there is a compiler bug? I do use ldc2 and `betterC`! Hello, not completely unrelated to your problem, I have also done something like that, and when you're in D, don't use simply a pointer and length like that, use the `slice` operator. See references: https://tour.dlang.org/tour/en/basics/slices https://dlang.org/spec/operatoroverloading.html#array-ops For example, you can make your pointer a lot safer by doing: ```d size_t length = 5; int* pointer = cast(int*)malloc(int.sizeof * length); //Don't int[] mallocArray = (cast(int*)malloc(int.sizeof * length))[0..length]; //Do ``` On the second way, you'll get bound checks, thus, making it safer. Also, no need to keep track of your length separately anymore. This is good practice in D language and you'll find yourself using this instead in the future. And yes, this works in betterC, it is a simple runtime check, completely `@nogc @safe nothrow` and every other kind of thing you would want.
Re: D DLL crashes if not run on the main thread
On Tuesday, 5 September 2023 at 22:45:28 UTC, raven09 wrote: Hi, I've compiled a DLL using D and intended to use it with a C# winforms app using P/Invoke. Everything works wonderfully as long as it is called from the main thread (at least I assume that it not being on the main thread is causing the issues). If I start a new thread and try using any function imported from the DLL the program will instantly crash. Debugging the winforms app with VS shows that it does indeed crash on that function call, but does not provide any more information. Further testing I did was writing a test DLL that basically just contained `` extern(C) export int TestMe() { return 5; }`` and calling it in a new C# program: it worked fine until I put it in a separate thread. [...] Hi, maybe you could try putting your DLL load function inside the thread which you're calling your function? Maybe there could be something related to that.
Hipreme's Tip of of the day #09 - Using D shared libraries with dub
Hello again! -- As of some requests in DConf, I'll post here some things related (or not) to dub recipes. Since there is so many ways to build D and dub is quite the main way, I'll try to show other uncommon ways to use it, this is more recommended to bigger projects since the standard one is enough for most. I have been involved with some problems while dealing with shared libraries. Specifically on Windows and here I am writing how you can integrate shared libraries to your project, since it is a super powerful tool for plugin development: For a dub.json configuration, let's first build your shared library: ```json "name": "shared_lib", "targetType": "dynamicLibrary", "dflags-ldc": [ "--link-defaultlib-shared" ] ``` The `--link-defaultlib-shared` here is the secret. It makes the D runtime be shared between the main D program and the shared library, with that, you'll get cool features such: - A single GC (don't use more than 1) - Able to share errors between those runtimes (you can do try/catch between them) - More debug information If you're using a shared library, you have a dependency and is on Windows, you'll need a special flag for avoiding a bug right now, this is some example: ```json "name": "shared_lib", "targetType": "dynamicLibrary", "dependencies": {"my_dependency": {"path": "libs/my_dependency"}}, "dflags-ldc": [ "--link-defaultlib-shared" ], "lflags-windows-ldc": [ "/WHOLEARCHIVE:my_dependency" ] ``` You can see the new linker flag `/WHOLEARACHIVE` followed by the dependency (output name) `my_dependency`. This is required for every dependency ~~because linkers are bad~~. Basically your symbols get stripped out when including a library to your shared library and this fixes the problem. As of 2023, a solution to that is being researched, but don't let that stop you from using shared libraries.
Re: Options for Cross-Platform 3D Game Development
On Wednesday, 5 July 2023 at 22:27:46 UTC, Andrew wrote: So, I've gotten the itch to have a go at game development in D, after doing a bit of it in Java last year. I've previously used LWJGL, which is a java wrapper for OpenGL, OpenAL, GLFW, and some other useful libs. The problem is, apparently OpenGL is deprecated for apple devices, so I don't really want to use that unless there are no decent alternatives. So far, the most promising I've seen is [bindbc-bgfx](https://code.dlang.org/packages/bindbc-bgfx), but it's been a pain to set up due to having to build the bgfx codebase, which requires a specific version of glibc that my distro (Linux Mint) doesn't offer yet. Are there any other recommendations for cross-platform rendering libraries? Of course I could use a pre-made game engine like Unity or Godot, but for me, most of the fun is in making the engine. To be honest, I'm accepting anyone on Hipreme Engine that is willing to help adding a shader transpiler or cross compiler. Right now I got an abstraction over opengl, direct3d and metal, for almost every basic stuff out there, which is really simple. Having the shaders being written once is pretty much the next step but I can't focus on that. You'll have a better experience with Hipreme Engine than mostly of the options you get here since you'll have a complete cross compilation env for you requiring no configuration at all.
Re: Unresolvable dependencies to package
On Friday, 14 April 2023 at 20:30:56 UTC, el machine code wrote: so my question why am i'm getting this error and how do i fix this? You need to make those depends on the same version somehow. From what I've looked. Luna maintains its own fork of bindbc-imgui. You're probably taking from another repository i.e: Not the one inochi creator uses. You'll need to clone https://github.com/Inochi2D/bindbc-imgui somewhere Then you'll need to look into your dub.selections.json to point "bindbc-imgui" to this folder.
Re: Is it possible to make a library (dll/so) from separated .d files?
On Monday, 3 April 2023 at 09:08:42 UTC, dog2002 wrote: Hello. The title sounds weird, but I try to explain it better. In Unreal Engine and Unity, source code files don't use main() and other important functions. They have only a class. Like this: ``` class SomeClass: someInterface { AFunctionFromTheInterface1() { } AFunctionFromTheInterface2() { } } ``` And then all the source code files will be compiled into a single .dll/.so library, so the game engine can use one in a game. I don't know what compiler does Unreal Engine use, but it uses C++. Is it possible to do so in D? Yes, actually, this is the very same approach I've done for my engine, since holding the main function I can take care of boring platform details. For doing that you'll need some way to make your main program know about your class. The way I do that is by defining another entry function which is always defined enemy you have a game project. You can take a look at https://github.com/MrcSnm/HipremeEngine/blob/66618c7783d62107bcaad393d5af5b86c9387b34/api/source/hip/api/package.d#L58 The user uses that engine mixin template, which will add the engine entry point to your game script, after that, whenever my engine loads the Dll, it will know what function to call and what scene it should spawn
Re: My tiny program still can't get FreeImage.dll to load... GLFW.dll library loads no problem...
On Wednesday, 15 March 2023 at 22:09:35 UTC, WhatMeWorry wrote: I appreciate all the help people have given me previously. So I've made everything super simple. The dub.sdl file consists of four lines: - Solution to this problem: Checking whether it exists is completely irrelevant if you don't pass absolute path to it. Plus, the load function checks whether it exists on system32 too. For a DLL to be load, it must be beside you .exe file. That means: exists() is relative to your working directory, dll load is relative to the directory the .exe is. - Better solution: There's no point into using libfreeimage. In D we already have Gamut[1] and [2] arsd:image_files. Both solutions is better suited to working with D as they use actual D syntax and features to make your code faster and safer, there will be no need to have a C compiler nor to pack a DLL together with your program. [1]: https://code.dlang.org/packages/gamut [2]: https://code.dlang.org/packages/arsd-official%3Aimage_files
Re: const in functions
On Sunday, 12 March 2023 at 15:09:45 UTC, Salih Dincer wrote: Hi, As someone who has used const very little in my life, I want to learn and ask: What are consts used in function parameters for; isn't there a copy already? Const is used for you not be able to change your values inside references. This is why we have const methods for example: ```d class Test { private int a; int getA() const {return a;} } ``` By having this property in your method, it says you're guaranteeing that Test won't be changed when this method is called, then, it'll be less time trying to find what mutated the object, so, use it as much as you can, but never overuse it since it is a pain to deal with. Const for value types is also used for not mutating them inside the function also leading to less debugging. Another use case for them is for compiler being able to infer some optimizations. If your variable is `immutable`, it becomes implicitly `__gshared`, which does not uses Thread Local Storage, another good thing for optimization in both memory and access.
Re: Can nice D code get a bit slow?
On Wednesday, 8 March 2023 at 10:49:32 UTC, Markus wrote: Hi, sorry for the broad and vague question. I have read in some reddit post about benchmarks, that some code didn't use the final keyword on methods in a sense that final would make it faster, I believe. [...] Don't bother with it. This kind of optimization is done when compiling with -O, and I really doubt about your bottleneck being that you're calling a virtual call. Wait when you actually need to optimize before making your code ugly.
Re: How to build a static lib properly?
On Monday, 6 March 2023 at 05:59:09 UTC, Mike Parker wrote: On Monday, 6 March 2023 at 02:09:23 UTC, ryuukk_ wrote: dub should build a static library for the project i build, that includes each library it uses that are referenced as "library" since the default is "staticLibrary" according to rikki What you're asking for is a different use case. `staticLibrary` is for compiling a specific dub package as a static library. It does not imply that all of that package's dependencies should also be compiled into a single static library. Nor should it. You're asking for a package and its dependencies to be bundled for use outside of the dub ecosystem as a single static library. I won't say it's not a legitimate use case, it's just not one that dub currently supports, nor was it originally intended to (I wouldn't expect it to be a common one either, but then again common expectations are always changing). As a potential dub enhancement, e.g., `staticLibraryBundle`, I do agree it's worth exploring. I don't believe you can expect every package to "just work" in that environment. As Steve mentioned, there will always be link-time dependencies to any shared libraries on which those bundled libraries depend. And some packages may be set up in a way that causes issues, as Rikki noted when he said he had to make some tweaks on his successful build. But for the time being, dealing with static libraries in D is just the same as dealing with them in the C and C++ world. They always have been a PITA to deal with, and that's why the trend in recent years has been to move away from them. Build tools like dub hide them from you when used as intended. It's when you mix build systems that you run into trouble. Still, I suggest you send an email to soc...@dlang.org as part of the Gripes and Wishes campaign so that this gets added into the dataset. Anything that enhances dub's usability should be looked at. Having a way to define a static library bundle is really great. It does help a lot when you create a package where it is initialized in non D code. Right now, this is the third time I'm going to need it for my engine, for MacOS I need to manually assign my dependencies, and having only the main code as a library doesn't work for that purpose. I have done before a simple program which executes dub describe for taking the dependencies then I build the program as a staticLibrary, problem is that this requires a 2-pass build and it is not standard.
Debugging memory leaks
I want to know if there is some way to debug memory leaks in runtime. I have been dealing with that by using a profiler and checking D runtime function calls. Usually those which allocates has high cpu usage so it can be easy for those bigger ones. While for the smaller ones, this approach doesn't seem to work and looking into my task manager I can see it increasing the memory usage very slowly. I wanted to know if there is an option to do that on RUNTIME. --vgc is not a good option as I don't care about allocations that happens on initialization code.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Thursday, 9 February 2023 at 22:34:29 UTC, ProtectAndHide wrote: On Thursday, 9 February 2023 at 20:05:06 UTC, Ali Çehreli wrote: On 2/8/23 04:07, zjh wrote: > Last time, someone proposed to add `private` like `C++'s`, We've discussed the 'private' topic very many times already. C++'s private necessitate the 'friend' keyword, which comes with it's own problems. Besides, D has zero problems with its private implementation in the sense that there has been zero bugs related to it being that way. Given the number of individuals who bring this topic up over and over up is so few that I don't think there is a common problem. Do you have actual bugs related to this? "Wanting" the inclusion of a feature is sufficient. In contrast, I use D every day and love its relaxed attitude towards private. > and then it > was the same,they are always unwilling to add facilities useful That is not correct. The truth is, nobody is jumping to implementations just because some people think they are useful. There are always valid reasons for including a feature or not. Ali You mentioned previously that D implements various things in unprincipled ways. I guess, if one wants to use D, one has to be comfortable with this. But using a relaxed attitude towards the implementation of such a common and important abstraction, that in turn allows me to so easily shoot myself in the foot, is not really an attractive feature .. to me ;-) btw. When a newbie to D raises ideas, suggestions, etc... and you counter them with (in essence) 'we don't need that in D, but go write a dip if you think we do' attitude, is a real turn off. Most of the time, when people use "private", they are actually shooting their users which can't even extend their class. I rarely see code which people use "protected" instead and I find that pretty lacking. One thing is hiding memory allocation details on your class, other thing is hiding a property which could and should be controlled when extended in a class. To be fair I'm more often than not against private variables. Most of the time it only caused me headaches because there was a lot of unimplemented features and I could not simply fork the project. This is not only in D. I got that in Java, Haxe, C#. Thankfully those languages has ways to simply ignore the private attribute, which can't be done in D. Anyway, I'm not against static classes and I don't think they would bring any inherent problems, they should not cause regression and they should be easy to implement as the compiler already has the tools for it
Re: A potential use-case for template mixins?
On Monday, 6 February 2023 at 12:22:19 UTC, Matt wrote: I am (still) writing a 3D graphics engine, and was considering my choices for a scene graph. Originally, I was going to use classes derived from my base SceneNode class for the nodes of the graph, but would this instead be a better situation to use template mixins instead of potentially having to include a lot of information in the base class? Or should I go with the traditional "everything is derived from the base class"? I understand if this is light on details, I'll try and provide more if necessary, but I'm really not far into the design beyond this, and was wondering which would make for an easier path in the future Use classes. Mixin template are only relevant to types which understands the mixin template or when you want to create a similar object with similar behavior, but they mustn't be the same thing. That means, you need to ducktype everything in order to work which could bring a template hell in your code. Unless you try to do generics in your code or make it componetized rather than inherited, but that could affect your coding style by manually passing the node that your object has, this can be quite the manual work though.
Re: hasUDA alternatives?
On Saturday, 28 January 2023 at 16:29:35 UTC, Anonymouse wrote: I use `hasUDA`, `getUDAs` and `getSymbolsByUDA` fairly heavily in my project. dmd requires some 3.2Gb to compile it, a dub recompilation taking somewhere around 8-14 seconds, depending on the phase of the moon. It's not too bad, admittedly. Stuff like this, naturally taken out of all context: ``` static if (isSerialisable!member) { import std.path : buildNormalizedPath; static if (hasUDA!(this.tupleof[i], Resource)) { member = buildNormalizedPath(state.settings.resourceDirectory, member); } else static if (hasUDA!(this.tupleof[i], Configuration)) { member = buildNormalizedPath(state.settings.configDirectory, member); } } ``` ``` private alias allEventHandlerFunctionsInModule = Filter!(isSomeFunction, getSymbolsByUDA!(thisModule, IRCEventHandler)); ``` ``` enum isSetupFun(alias T) = (getUDAs!(T, IRCEventHandler)[0]._when == Timing.setup); enum isEarlyFun(alias T) = (getUDAs!(T, IRCEventHandler)[0]._when == Timing.early); enum isLateFun(alias T) = (getUDAs!(T, IRCEventHandler)[0]._when == Timing.late); enum isCleanupFun(alias T) = (getUDAs!(T, IRCEventHandler)[0]._when == Timing.cleanup); alias hasSpecialTiming = templateOr!(isSetupFun, isEarlyFun, isLateFun, isCleanupFun); alias isNormalEventHandler = templateNot!hasSpecialTiming; alias setupFuns = Filter!(isSetupFun, this.allEventHandlerFunctionsInModule); alias earlyFuns = Filter!(isEarlyFun, this.allEventHandlerFunctionsInModule); alias lateFuns = Filter!(isLateFun, this.allEventHandlerFunctionsInModule); alias cleanupFuns = Filter!(isCleanupFun, this.allEventHandlerFunctionsInModule); alias pluginFuns = Filter!(isNormalEventHandler, this.allEventHandlerFunctionsInModule); ``` If `hasUDA` and friends are so bad[1] [2] [3], what can I use instead? I need them to work at compile-time. `hasUDA` just needs to evaluate to true or false, but for `getUDAs` and `getSymbolsByUDA` I need them to resolve to symbols (and not string names of symbols). Do I have any alternatives? [1]: https://forum.dlang.org/post/bwekufskjmknllapz...@forum.dlang.org [2]: https://forum.dlang.org/post/tm02a6$nk3$1...@digitalmars.com [3]: https://forum.dlang.org/post/nzlnwbcezwyopjfia...@forum.dlang.org So, for that, having an exclude keyword would be nice. But for right now, I would like to check a better solution with you. Building my entire engine takes in LDC 250mb, in DMD I wasn't able to check but it seems to use really little. From [2], FeepingCreature says that using udaIndex is better than using hasUDA and getUDAs. getUDAs can be simply changed to `__traits(getAttributes, yourMemberHere)`. Many std.traits things actually uses `Filter!()` which is a recursive template using `static if` + `AliasSeq`. Recursive templates are super heavy. In general, recursive functions always spells "slow" in any place. The best thing to avoid in phobos are those recursive kinds, specially if you're using for too many places. So, what can I do if I wish to construct a better filter? Well. Construct an array of indices to your filtered types instead of an AliasSeq. It is impossible to construct procedurally an AliasSeq without using recursive templates. That way you could iterate through those indices instead. It is a little more manual work, but it is better on long run specially when you're not going to keep changing your reflection functions any soon So, avoid Filter which seems to be your main bottleneck there. Specially because you will iterate all members many times. It is always best to do a single iteration and using the same data. Your code seems to be analogous to doing: ```d alias setupFuns = Filter!(isSetupFun, this.allEventHandlerFunctionsInModule); alias earlyFuns = Filter!(isEarlyFun, this.allEventHandlerFunctionsInModule); ///Pseudo code expanded representation: template setupFuns alias pred) { alias Filter = AliasSeq!(); static foreach (member; Module) static if (pred!arg) Filter = AliasSeq!(Filter, arg); } template earlyFuns(alias pred) { alias Filter = AliasSeq!(); static foreach (member; Module) static if (pred!arg) Filter = AliasSeq!(Filter, arg); } ``` A better solution would be: ```d static foreach(mem; __traits(allMembers, thisModule)) { static if(is(typeof(__traits(getMember, thisModule, mem)) == EarlyFunc)) else static if(is(typeof(__traits(getMember, thisModule, mem)) == LateFunc)) } ``` That way, you would avoid: Recursive template executed a lot of times + you would use reflection once (iterate once vs iterate n times).
Re: Hipreme's #8 Tip of the day - Using custom runtime with dub projects
On Sunday, 22 January 2023 at 17:06:13 UTC, evilrat wrote: On Sunday, 22 January 2023 at 16:57:56 UTC, Hipreme wrote: The way to use dub's packages is by using the DFLAGS. With DFLAGS, I can set the import path to my own DRuntime and own std. That way I can make the dependencies behave more or less the same, this is an example of what is being done now: Keep in mind that you'll probably need to setup some env variables such as mine done for making your script a little more portable to other developer's PCs. I would really like if there was a way to define global dflags on dub though. Can't you just use env variable[1] and put into dub dflags like this? https://github.com/Superbelko/ohmygentool/blob/cc75d915a8df8bdc2bba628df305d421151994a1/dub.json#L11 _(note that some of the listed predefines doesn't work in some sections though, a bug maybe?)_ [1] https://dub.pm/package-format-json.html#environment-variables Nope. Those DFLAGS environment variable is used to affect projects such as my dependencies. For example, my dependency needs to be built using my own runtime. The dflags defined in the dub.json only affect the current project, not its dependencies
Hipreme's #8 Tip of the day - Using custom runtime with dub projects
I have been working with WebAssembly for at least 1 entire month into getting my entire Game Engine and DRuntime ported to it. As I'm almost reaching the point of the new announcement, I come here to show how I've done DUB's dependency compatibility with a custom runtime. The way to use dub's packages is by using the DFLAGS. With DFLAGS, I can set the import path to my own DRuntime and own std. That way I can make the dependencies behave more or less the same, this is an example of what is being done now: ``` set DFLAGS=-I=%HIPREME_ENGINE%/modules/d_std/source ^ -I=%HIPREME_ENGINE%/build/wasm/runtime/webassembly/arsd-webassembly ^ -preview=shortenedMethods ^ -L-allow-undefined ^ -fvisibility=hidden ^ -d-version=CarelessAlocation dub build --build=debug -c wasm --arch=wasm32-unknown-unknown-wasm ``` So, when dub tried to build their dependencies, your custom runtime overrides D's default ones. In that case I'm overriding both D std and D core/** and object.d Keep in mind that you'll probably need to setup some env variables such as mine done for making your script a little more portable to other developer's PCs. I would really like if there was a way to define global dflags on dub though.
Re: How to write a library
On Saturday, 21 January 2023 at 22:53:19 UTC, Matt wrote: I am trying to write a graphics engine for my university capstone project, and really wanted to give it a try in D, as both a talking point, and because I love the language. I'm using dub to build the library, and the demo application that'll use it. However, I've come across a problem. In C/C++, when you build a library, you compile and link the source, then provide the header files for the library user to include. I have built the library, but what is the D equivalent to header files, and what do I have to do to prepare and use my library in another project? For using your thing as a library you need to do 2 things: 1: Include the library files by using `importPaths` on dub or -I= on your favorite compiler 2: Add the linker flag to include the library. importPaths don't compile your source files. Only templates and some ctfe features can be used when using importPaths.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Friday, 20 January 2023 at 11:28:23 UTC, thebluepandabear wrote: Hi, In Java/C# you can create purely static classes. These are classes whose methods are all static, the classes cannot be derived from or instantiated: ``` static class Algo { void drawLine(Canvas c, Pos from, Pos to) { .. }; } ``` There are 2 solutions for that. One involved doing a private implementation: ```d module drawer.impl; void drawLine(...) ``` Then, you create another file: ```d module drawer; public import Algo = drawer.impl; ``` After that, you can use it as `Algo.drawLine`. With a single file, you can do: ```d final class Algo { @disable this(); static: void drawLine(...){} } ```
Re: How to access private variable of outer class from an inner struct
On Sunday, 15 January 2023 at 12:44:51 UTC, thebluepandabear wrote: Thanks. How will the variable `outer` become the reference to the current `X` object (if that makes sense?). Does the compiler do it automatically? You'll have to create your struct like `return Y(this)`. It basically depends on how you're using the struct
Re: Mixin helper help
On Thursday, 12 January 2023 at 08:03:34 UTC, John Chapman wrote: I'm obviously doing something wrong, but don't quite understand. ```d mixin template helper() { mixin("writeln(12);"); } struct Foo { void opDispatch(string name)() { import std.stdio; mixin helper!(); //mixin("writeln(12);"); } } void main() { Foo.init.opDispatch!"bar"(); } ``` The compiler emits these errors about the mixin ("writeln(12);"): unexpected `(` in declarator basic type expected, not `12` found `12` when expecting `)` no identifier for declarator `writeln(_error_)` semicolon expected following function declaration declaration expected, not `)` Why does the commented code work but the mixin not? Thanks for any pointers. `mixin template` cannot be used like that. The only statement it accepts are declaration statements: Look at https://dlang.org/spec/module.html#MixinDeclaration It says it must compile to a valid DeclDef, which means you can't put code like that. Mixin templates are used only for declaring new variables, types and functions, it can't simply put call statements like that. You could do this by simply calling a function such as: ```d void helper() { writeln(12); } ``` I think you'll need to comment more on your problem if you wish specialized help
Hipreme's #7 Tip of the day - Using the out parameters
So, after some time using D, I found out that `out` isn't used in so many cases, but when used, it can be quite confusing, because if you don't read the documentation, it will be unclear that something is an `out` parameter, specially if you're reading a code that is not yours. Before using `out`, I found myself using more the address operator (&), because it made clear that the target variable would be initialized, but there is an even better and safer way to do that: So, the best practice when using `out` parameters that I found right now and it becomes way clearer and can increase your performance if you're in a hot path is by void initializing your out variable, e.g: ```d void initializeFloat(out float f){f = 0.0f;} void main() { float myFloat = void; initializeFloat(myFloat); } ``` See that without the `void` initialization, all that rests is the function name which is quite readable `initializeFloat` so, something should happen to it. But there are cases which your naming won't be enough expressive to say that you're using an `out` parameter. This situation, void initialization (no initialization at all), is both faster and self documenting for your code, so, try to remember that feature, it took me some time to start using and I just remembered it existed when I was dealing with returning float vertices and there was so many that it appeared on my profiler.
Re: Idiomatic D using GC as a library writer
On Sunday, 4 December 2022 at 09:53:41 UTC, vushu wrote: Dear dlang community. I am unsure about what idiomatic D is. Some of the Dconf talks tells people just to use the GC, until you can't afford it. If there are documents that describes what idiomatic D is then I would appreciate it. So my questions are: What are your thoughts about using GC as a library writer? If you wan't to include a library into your project aren't you more inclined to use a library which is gc free? If that is true, then idiomatic D doesn't apply for library writers. Since to get most exposure as a D library writer you kinda need to make it gc free right? Cheers. "Until you can't afford", is something really extreme. There is a bunch of ways to deal with GC memory, what I would say that can't afford is when you're constantly allocating memory and because of that, making the program more prone to execute a collection. I haven't had any problem with the GC yet. If you think your program is slow, pass it on a profiler and you'll know the real problem. Don't think too much about that or else you're gonna lose a heck lot of productivity and end up creating needlessly unsafe code. If you're still gonna be hard headed against the GC, at least use slices when allocating from malloc, makes your code safe, readable and less variables to think about. Don't use raw pointers unnecessarily, and right now, the only reason pointers have been used in my code base was not for allocated memory, but for being able to modify a variable from another place when you need to store a variable reference. If you're only gonna modify it inside the function, use `ref` instead.
Re: Can we ease WASM in D ?
On Wednesday, 16 November 2022 at 22:51:31 UTC, bioinfornatics wrote: Dear community, I look some day ago to the D wasm page: -> https://wiki.dlang.org/Generating_WebAssembly_with_LDC And since then I ask myself can we at compile time convert a D code to an extern C code for wasm ? Indeed, if a library/framework would wrap this to let end user write his code in plain D that would be awesome. So did you think it is possible to do it by using metaprogramming, mixin, mixin template, mixin string … ? Thanks for your ideas It should not be too hard to do that using mixin templates. The concept is the same from my `@ExportD` that I'm using on my engine. What `@ExportD` does is to create a new function based on the function target function [or even classes] which all it does is call that (or even attach a GC.root as needed ), and generates factory functions for classes or create some `extern(C) export` the function. I have done the same thing also for Lua and Java, don't seem that hard to do it with WASM. The only difference is that you will need to mixin template yourself (I do it at the end of file), then I iterate through the module members containing your `@wasm` UDAs, and generate the functions needed. Remember that you could also use things such as `@wasm("myNewFunctionName")` and handle such cases. But for me, working with D without a D runtime is simply not worth. That being said, if we had a working D runtime for WASM I would be adapting my engine to support it too.
Re: Can't assign extern(C) function pointer to D variable?
On Tuesday, 22 November 2022 at 21:11:37 UTC, XavierAP wrote: I was surprised when it didn't compile, though I immediately found it understandable... Already read through https://dlang.org/spec/interfaceToC.html and https://wiki.dlang.org/Bind_D_to_C [...] You need to create an alias containing your callback type. ```d alias DCallback = extern(C) void function(); DCallback cb; cb = yourCFunction; ```
Re: Get the class name without casting the type
On Tuesday, 15 November 2022 at 11:42:59 UTC, Alexander Zhirov wrote: Is there any way to get the name of class B? ```d interface A { string text(); } class B : A { override string text() { return ": It's ok!"; } } void main() { A[] a = cast(A[]) new B[3]; B b = new B(); fill(a, b); foreach (val ; a) { writeln(typeof(val).stringof, val.text()); } } ``` Output: ```sh A: It's ok! A: It's ok! A: It's ok! ``` You can do it as `val.classinfo.name`
Hipreme's #6 Tip of the day - Knowing when and how to use dub's Have_version
Although I really don't like many things about how dub does, it brings many facilities. Imagine the following project structure: Project A is using library B Now, imagine that our `module b` has the following code: ```d module b; void print(string s){imported!"std.stdio".writeln(s);} else version(Have_A) { void printA(string s){imported!"std.stdio".writeln("Printing from A!");} } ``` Now, using the project A: ```d module a; void main() { import b; printA("Printing from my project"); } ``` Now, do try to build it. It compiles! But then you get a linker error! `Unresolved external function printA`. Now, do you understand why this just happened? If you execute `dub --verbose` You will be able to understand what just happened: Build command for B: `dmd b.d -lib` Build command for A: `-Imodule/b -version=Have_A b.lib a.d` So: Your function printA does not get included in the process! As when the `b.lib` was built, there wasn't any version for doing the implementation, but when A imported B, it basically imports B as: ```d void print(string s); void printA(string s); ``` So, it won't be actually implementing your function, it just knows about the symbol existence, so, why should you ever use Have_version? The following code for B would have worked: ```d module b; //Same thin above void print(string s)... version(Have_A) { public import a.print_a_implementation; } ``` That way `module a.print_a_implementation` and then, you can guarantee that your code will be included (if print_a_implementation.d exists in your project)! So, the key way to think about this is by when thinking about using `version(Have_LibraryNameHere)`, you will need to think about a 2 compiler passes, one for implementing the functions, another for including them. If you remember that, you won't do the same mistake as me :)
Hipreme's #5 Tip of the day - Avoid raw pointers at all cost
Attention, C and C++ programmers are more likely to use what I'm going to talk about. If you're a C++ programmer, you're probably thinking about shared/unique pointers. But that's not what this is about. Take the `void*` type. This type can be pretty much anything, this is "okay" if you wanted to make your code more generic, but there is a much better way to handle that. Look at that code: ```d import core.stdc.stdlib; void* myInt = malloc(int.sizeof); *(cast(int*)myInt) = 500; writeln(*(cast(int*)myInt)); free(myInt); ``` This is a code that can be common to happen on C, but you can do it a lot better. You can actually make your casting a bit saving information about its size, you could do it with a struct, but you could also do it with one of the D features: slicing: ```d import core.stdc.stdlib; void[] myInt = malloc(int.sizeof)[0..int.sizeof); ``` Now, you will have information saved on how much info is allocated on your int by doing `myInt.length`. Which means that any attempt to assign data to the pointed location, this location will be bound checked. Another thing I strongly recommend is not using malloc. The first reason is that it makes your code harder to read, unsafe, untraceable and longer. If you just use instead: ```d void[] myInt = new void[int.sizeof]; ``` Will basically have the same effect of the code before in terms of usage, no import, less to write, traceable code (-profile=gc). Now, if you need to use that just for the sake of generic data and no heap allocation is really needed, I must recall on your mind the underused `union` and the underused `std.variant` (aka Tagged Union). My own way to use union if you don't need the tagged union as you already know how your data flow works, this is a pattern that I shall do it from now on (specially because you won't be casting your data all the way instead of just using `cast(Something*)(voidPointerData)`: This is an example of my generic audio buffer pool for various audio APIs ```d union HipAudioBuffer { version(OpenAL) { import openal; ALuint al; } version(OpenSLES) { import opensles.slinterface; SLIBuffer* sli; } version(XAudio2) { import directx.xaudio2; XAUDIO2_BUFFER* xaudio; } } ``` Then, instead of just casting your data from void*, you can just access the "cast" itself as a property.
Re: Passing a string by reference
On Tuesday, 8 November 2022 at 12:30:50 UTC, Alexander Zhirov wrote: Do I understand correctly that in order for me to pass a string when creating an object, I must pass it by value? And if I have a variable containing a string, can I pass it by reference? Should I always do constructor overloading for a type and a reference to it? In the case of the variable `c`, a drop occurs. Why? An object is not being created on the stack? ```d import std.stdio : writeln; class A { private string str = "base"; this(ref string str) { writeln("type reference string"); this.str = str; } this(string str) { writeln("type string"); this.str = str; } this() {} void print() { writeln(str); } } void main() { auto a = new A("Hello, World!"); // this type string a.print(); string text = "New string"; auto b = new A(text); // this type reference string b.print(); A c; c.print(); // segmentation fault! Why not "base"? } ``` You forgot to assign "c" to anything, I think you meant: `A c = b;` Read that segmentation fault as null pointer exception. Whenever you assign something to `ref type something`, it will basically be the same as writing `myVariable = *something;` in C code, so, in that case, it won't make any difference. The `ref` attribute only means that if you change your string inside the code that takes by ref, it will reflect when returning, such as: ```d void modifyString(ref string input) { input~= "Now it is modified"; } string text = "New string"; modifyString(text); writeln(text); //"New stringNow it is modified" ```
Re: Linking not working properly Windows 11
On Saturday, 5 November 2022 at 19:19:09 UTC, bauss wrote: On Saturday, 5 November 2022 at 14:54:52 UTC, Hipreme wrote: [...] I have both VS 2019 and 2022, but only 2019 has c++ build tools etc. I assume that should be fine? [...] You forgot to put \link.exe in the path
Re: Linking not working properly Windows 11
On Saturday, 5 November 2022 at 14:14:16 UTC, bauss wrote: On Saturday, 5 November 2022 at 13:42:08 UTC, rikki cattermole wrote: Try ldc, if that works then its just a missing library that needs to be linked against regarding MS CRT. Using LDC doesn't seem to work either, it has similar linking problems. ``` lld-link: error: undefined symbol: fileno referenced by druntime-ldc.lib(dmain2.obj):(_d_print_throwable) referenced by phobos2-ldc.lib(stdio.obj):(_D3std5stdio4File4syncMFNeZv) referenced by phobos2-ldc.lib(stdio.obj):(_D3std5stdio4File13windowsHandleMFNdZPv) referenced 18 more times lld-link: error: undefined symbol: execv referenced by phobos2-ldc.lib(process.obj):(_D3std7process6execv_FIAyaIAQfZi) lld-link: error: undefined symbol: execve referenced by phobos2-ldc.lib(process.obj):(_D3std7process7execve_FIAyaIAQfIQeZi) lld-link: error: undefined symbol: execvp referenced by phobos2-ldc.lib(process.obj):(_D3std7process7execvp_FIAyaIAQfZi) lld-link: error: undefined symbol: execvpe referenced by phobos2-ldc.lib(process.obj):(_D3std7process8execvpe_FIAyaIAQfIQeZi) lld-link: error: undefined symbol: tzset referenced by phobos2-ldc.lib(timezone.obj):(_D3std8datetime8timezone9LocalTime9singletonFNeZ12__dgliteral4MFNaNbNiNfZOb) Error: linking with LLD failed ldc2 failed with exit code 1. ``` Not sure what to do at this point. Just posted the other day how to use the MSVC Linker on windows. Using LLD is quite complicated in my experience because I was getting a lot of undefined symbols from the libcmt. Check this post: https://forum.dlang.org/thread/frixfbbucsbgcrsvm...@forum.dlang.org Remember that for using the MSVC Linker you will need to have visual studio build tools on your PC (or install the visual studio with desktop development with C++). Then you can modify your `sc.ini` and it should work.
Re: Hipreme's #4 Tip of the day - Don't use package.d
On Saturday, 5 November 2022 at 01:34:04 UTC, ryuukk_ wrote: On Friday, 4 November 2022 at 10:57:12 UTC, Hipreme wrote: Package.d is a real problem existing on our currently modules design. First is that it means to take the directory name to use as a module. This is a problem for 3 reasons: 1. You won't be able to find your module by the file name. This is incredibly common, for instance, in Visual Studio Code, when you hit CTRL+P and type the file name, nope, you will need to write path/to/folder/package.d, beyond that, when you search package.d there will be so many files with the same name. 2. As being an exception to how the module system works, this has already caused me a few headaches (inexplicable bugs), that happens with symbols aliasing, when the time it happened, I had no idea on what it could be and I don't even remember how I solved, instead, I only knew it was related to package.d. 3. I'm currently having a bug on my API module that every duplicated file name, even when located at different directories(modules), are generating duplicate symbol. The major problem is that this is currently undebuggable, as the MSVC Linker does not show the full directory of the libraries/object files that caused this clash, not even the symbol! The duplicate symbol currently only happens in MSVC Linker, which makes me think if the bug is in the D language or the linker itself, as on LLD this does not happen. So, my current advice is always try making your file names unique, this will bring a much better debuggability in your project. i use that feature a lot, just search with the folder name, then "package" https://i.imgur.com/cHb7isl.png it's also very useful to avoid having all of your code in a giant unreadable single file it's also very useful to avoid using dub.. just an import path to the folder and that's it https://i.imgur.com/Wy6WOXK.png also very useful when you want to simplify using importc, put your c files under the c folder, and the package.d, public import the c files, and you can put some helper code in D there, very nice to have I believe that needing to write `package.d` manually is pretty useless. Most of the time it means "import everything from this directory". The only real usage that helped me is when I needed to create a `version(Release) import something.opt; else version(Debug) import something.hotload;` basically. But that does not really require package.d. Those historic issues that Adam said are the real cause of their current design. Take into account how would you do it in Java. `import mypackage.*;` is how it was done, and I haven't never had any problem doing this, and this is pretty descriptive. package.d feels a lot more Haxe's `import.hx`, but it has a main difference that import.hx is a REAL special file that changes a bit on what happens on your source files. They are automatically included in its dir/subdir (think of a per directory object.d). The problem is that I'm not saying package.d is worthless, but it is a pool of bugs in the language that needs a real fix and only that post has already showed 4 bugs people have had. (Although I still don't like searching files by package.d, it is counter intuitive).
Re: Hipreme's #4 Tip of the day - Don't use package.d
On Friday, 4 November 2022 at 16:21:17 UTC, z wrote: On Friday, 4 November 2022 at 10:57:12 UTC, Hipreme wrote: ... What do we use instead? I won't lie about the fact package.d forced me to workaround elusive "bugs" in my usage(1) but what is the alternative if we don't want to work around it? (1)(ime : had cases of package.d requiring compiler specific pragmas for LDC, and dub can't find the package's `source` files at all if it's a multi file subpackage intended to be imported only, i never got it working with `package.d`, only a single source file setup `*packagename*.d` would work...) You can use any name instead. The only difference between an ordinary source file and a package.d is the module name. For instance, if you're inside the filesystem directory, you can change the name to literally anything and import instead. To make my engine's names unique I have been using a convention for the package.d names as an abbreviation of the directory name plus `definitions` or something like that.
Re: Hipreme's #4 Tip of the day - Don't use package.d
On Friday, 4 November 2022 at 14:11:55 UTC, bauss wrote: On Friday, 4 November 2022 at 10:57:12 UTC, Hipreme wrote: ... I disagree completely with being against package.d. Having used D for like a decade at this point, I've never experienced any issues with it. Most issues seems to be for newcomers and people who aren't entirely familiar with how D modules and packages work. package.d is absolutely essential in some cases. Literally my linker error disappeared after I changed it to another name. And I can't see how essential package.d is, there's no D difference in the code written. As it being the exception inside our compiler, it is an entire pool for bugs to get wild out there.
Hipreme's #4 Tip of the day - Don't use package.d
Package.d is a real problem existing on our currently modules design. First is that it means to take the directory name to use as a module. This is a problem for 3 reasons: 1. You won't be able to find your module by the file name. This is incredibly common, for instance, in Visual Studio Code, when you hit CTRL+P and type the file name, nope, you will need to write path/to/folder/package.d, beyond that, when you search package.d there will be so many files with the same name. 2. As being an exception to how the module system works, this has already caused me a few headaches (inexplicable bugs), that happens with symbols aliasing, when the time it happened, I had no idea on what it could be and I don't even remember how I solved, instead, I only knew it was related to package.d. 3. I'm currently having a bug on my API module that every duplicated file name, even when located at different directories(modules), are generating duplicate symbol. The major problem is that this is currently undebuggable, as the MSVC Linker does not show the full directory of the libraries/object files that caused this clash, not even the symbol! The duplicate symbol currently only happens in MSVC Linker, which makes me think if the bug is in the D language or the linker itself, as on LLD this does not happen. So, my current advice is always try making your file names unique, this will bring a much better debuggability in your project.
Hipreme's #3 Tip of the day - Changing DMD linker on Windows
The linker used on Windows when installing DMD is pretty much decided on how your PC was setup. - If you had Visual Studio installed on your windows for "Desktop Development with C++" before downloading DMD (from the site and setup), you will pretty have MSVC Linker as a default. - If you installed DMD before Visual Studio without that extension, your default linker will be LLD linker. There is 2 ways to change your linker for DMD: 1. Open a Command Prompt and type `set LINKCMD=path\to\the\linker`. 2. Open your D windows installation folder (usually C:\D\dmd2\windows\bin), and edit `sc.ini`. There will be [Environment]. Below [Environment], you just type the same thing as above. So basically, for my folder system, I can use both: **LLD**: `LINKCMD=C:\D\dmd2\windows\bin\lld-link.exe` **MSVC**: `LINKCMD=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\bin\Hostx86\x64\link.exe` Notice that there is no `""` (string literal), although you can find that on other places, that actually causes an error on windows. This can be useful for making your program link faster (lld is well known for that). But there are cases that you're going to need the MSVC one. Specially today that I was getting the error while trying to build with LLD: Error 0xc7b “Application was unable to start correctly” This was solved after changing my linker back to MSVC.
Re: Importing modules under DUB on Windows
On Wednesday, 26 October 2022 at 22:51:53 UTC, DLearner wrote: On Wednesday, 26 October 2022 at 18:53:58 UTC, Hipreme wrote: On Wednesday, 26 October 2022 at 18:37:00 UTC, DLearner wrote: On Wednesday, 26 October 2022 at 16:58:08 UTC, H. S. Teoh wrote: On Wed, Oct 26, 2022 at 04:20:01PM +, DLearner via Digitalmars-d-learn wrote: [...] Maybe try instead: "importPaths": [ "C:\\Users\\..." ] since the error message indicates that it expects an array, not a string. T Thanks for this. Following your suggestion, seems that DUB found the module (as it got through to the linking step without complaint), but then the linker failed to resolve the function name. However, when I moved the module to the project `'source'` directory (and took out the `importPaths` JSON entry), everything worked. But I don't really want to do this - the module is my collection of utilities, used in a variety of projects, so doesn't really belong within one specific project. Best regards The linker failed to resolve because it didn't include the symbols you imported. Think of import a way to the compiler resolve the compilation. Think of source a way to both the compiler and the linker to resolve compilation and linking. If you give only the import path, you will need a library. What you actually want is to put your new importPath to the JSON array `sourcePaths` Added `"sourcePaths": [ "C\\Users\\..." ]` Unfortunately failed with `core.exception.AssertError@source\dub\internal\vibecompat\inet\path.d(222): Trying to append absolute path.` I tried to construct a relative path to the module directory from the project directory, that didn't work either. Okay. So this error is very strange, the other thing I can give you advice is: If your other thing is another dub project, you can add it as a dependency by putting in your dub.json ```json "dependencies" : { "your_project_name" : {"path" : "your/path/here"} } ``` AFAIK, there is no problem in putting an absolute path dependency, in fact, I'm using things from another drive letter.
Re: Importing modules under DUB on Windows
On Wednesday, 26 October 2022 at 18:37:00 UTC, DLearner wrote: On Wednesday, 26 October 2022 at 16:58:08 UTC, H. S. Teoh wrote: On Wed, Oct 26, 2022 at 04:20:01PM +, DLearner via Digitalmars-d-learn wrote: Hi Never used DUB before. Wanted to use a function stored in a module outside the main source. Main source has `import ;` Put a line into the JSON: `"importPaths": "C:\\Users\\..."` pointing to the directory holding the module. `dub run` failed with `Expected JSON array, got string`. Maybe try instead: "importPaths": [ "C:\\Users\\..." ] since the error message indicates that it expects an array, not a string. T Thanks for this. Following your suggestion, seems that DUB found the module (as it got through to the linking step without complaint), but then the linker failed to resolve the function name. However, when I moved the module to the project `'source'` directory (and took out the `importPaths` JSON entry), everything worked. But I don't really want to do this - the module is my collection of utilities, used in a variety of projects, so doesn't really belong within one specific project. Best regards The linker failed to resolve because it didn't include the symbols you imported. Think of import a way to the compiler resolve the compilation. Think of source a way to both the compiler and the linker to resolve compilation and linking. If you give only the import path, you will need a library. What you actually want is to put your new importPath to the JSON array `sourcePaths`
Re: Hipreme's #2 Tip of the day - Reducing .di files dependency
On Tuesday, 25 October 2022 at 12:29:50 UTC, Andrey Zherikov wrote: On Sunday, 23 October 2022 at 20:12:46 UTC, Hipreme wrote: This will greatly reduce the number of import and dependencies you need if you ever need to distribute a library. Could you elaborate more on the benefit? Does it reduce compilation time for dependency? If so then how much? The main problem of that is when you actually get an import the user does not need to know. This is especially useful for dub projects, which if you import an internal dependency of the project, think of a renderer. I have the HipremeRenderer which uses OpenGL and DirectX-D. What if I show that I'm importing directx-d which is so huge? What if I'm just showing my .di files and the library file? The user would not be able to use the library without getting directx-d. And even worse, if I already guarantee that my renderer is self contained, why would I make someone need to import another library just to use mine? This is how it helps, the compilation times depends on how much code your dependency have, if it was std.regex, it could save you 2 to 3 seconds.
Hipreme's #2 Tip of the day - Reducing .di files dependency
For reducing a D Interface file dependency when generating it with the `-H` flag for DMD, you can't import a module on the top level. Take a look at that example: ```d module a; import std.stdio; void printSomething(string a) { writeln(a); } ``` If you generate the .di interface file while using dmd, it will pretty much generate: ```d module a; import std.stdio; void printSomething(string a); ``` Using the import inside the function scope, it will make the work easier for dmd: ```d module a; void printSomething(string a) { import std.stdio; writeln(a); } ``` Will actually generate only: ```d module a; void printSomething(string a); ``` This will greatly reduce the number of import and dependencies you need if you ever need to distribute a library.
Re: [Help Needed] - Debugging compilation time
On Friday, 21 October 2022 at 18:10:39 UTC, ryuukk_ wrote: I tried your project: Linux x64 ``` git clone https://github.com/MrcSnm/HipremeEngine.git cd HipremeEngine dub build (once to download dependencies if any) time dub build -f real0m4.604s user0m3.686s sys 0m0.900s ``` 4.6 sec for a FULL rebuild doesn't seem that bad and ``` real0m1.730s user0m1.480s sys 0m0.245s ``` after editing one module, not bad at all As other people say: LDC for release with optimizations DMD for development THat's what i personally do I'm not using anti virus :c Seems that Linux really is significantly faster for building , 1.7secs for a rebuild seems pretty nice for me, though I can't say it happens the same on my ground
[Help Needed] - Debugging compilation time
Hey guys, I have been complaining a lot of time right now from D compilation speed at least for my project. I have: - Underused CTFE - Underused Templates - Avoided importing standard libraries - Created a multi module projects for better code reuse Those are all the techniques I have tried to maintain my compilation times lower, yet, It still builds slow even when using the --combined (which does a single compiler run on dub) So, doesn't matter if all is imported at once or not, it seems the problem seems to be somewhere in my project which I've been unable to find. I wanted to show someone who is more experienced on the time trace from LDC to check what I've been doing wrong. This time trace took 9 seconds. DMD takes 7 seconds to build my project. Adam has built his entire arsd in 2.5 seconds, while my PC is faster and arsd is much bigger than my project, this does not make any sense. So I would gladly wish you guys help: My repository: https://github.com/MrcSnm/HipremeEngine/ My time trace: https://ufile.io/gmvw1wlu (This time trace will be in air for 30 days only)
Hipreme's #1 Tip of the day
Hey guys, I'm going to start making a tip of the day (although I'm pretty sure I won't be able to give every day a tip), but those things are really interesting to newcomers to know and may be obvious to some of the old schoolers there. Always public import a type that the user (including you) is expected to interact with: Imagine we have a module A that define a tree ```d module a; struct Tree(T){} ``` If you create a module b containing a function that returns a tree: ```d module b; import a; Tree!string getDirectoryTree(string entry){return null;} ``` This is virtually unusable! One must `public import a: Tree;` This will make your API a lot easier to interact with, keep in mind to always public import some type that is used from another dependency like this, but try to not overdo it.
Re: warning LNK4255 - How to solve this warning
On Tuesday, 18 October 2022 at 19:38:39 UTC, Ali Çehreli wrote: On 10/18/22 12:26, Hipreme wrote: > Is there any way to know which files produced this error or at least the > symbol names that are clashing? I'm totally helpless about this error. There is 'nm' on Posix systems that lists symbols in object files (including libraries and programs). Ali I have added under lflags : "/VERBOSE" which activates the verbose mode and "/WX" which treats the warnings as errors (because there is just so many things on linking step) I found some functions but nothing of them feels out of the ordinary. Treating this module as sourceLibrary instead of staticLibrary doesn't cause this warning though
warning LNK4255 - How to solve this warning
I get the warning `warning LNK4255: library contain multiple objects of the same name; linking object as if no debug info` when dealing a project with multiple static libraries. Is there any way to know which files produced this error or at least the symbol names that are clashing? I'm totally helpless about this error.
Re: How to check if a class has a specific overload for member x?
On Sunday, 31 July 2022 at 19:25:51 UTC, Hipreme wrote: I wish to generate some functions using mixin template and I wish to check if the current class already has an specific overload with parameters (A, B). What I'm currently trying is doing `__traits(getOverloads, T, "foo")`, and then checking if its type are equal. But it seems hackish, and I would like to make something like `hasOverload!(Test, "foo", int(int a, int b) const)` or something like that. Seems that is how it should be checked: ```d enum hasOverload(T, string member, FuncType)() { bool ret; static foreach(overload; __traits(getVirtualMethods, T, member)) if(is(typeof(overload) == FuncType) && !__traits(isAbstractFunction, overload)) ret = true; return ret; } ```
How to check if a class has a specific overload for member x?
I wish to generate some functions using mixin template and I wish to check if the current class already has an specific overload with parameters (A, B). What I'm currently trying is doing `__traits(getOverloads, T, "foo")`, and then checking if its type are equal. But it seems hackish, and I would like to make something like `hasOverload!(Test, "foo", int(int a, int b) const)` or something like that.
Iterating over mixin template members
So, I've came to a situation where I must use mixin template for defining members overloads, like: ```d mixin template OverloadGen() { static if(hasMethod!(typeof(this), "add", int, int)) { float add(float x, float y){return x+y;} } static if(hasMethod!(typeof(this), "mul", int, int)) { float mul(float x, float y){return x*y;} } } ``` I know this example is obvious, but I'm using this for a far more complex, so I need that to work. The current way I tried to solve that was using string mixins such as: ```d enum mixOverloadGen() { return q{ mixin OverloadGen __ogen__; static foreach(mem; __traits(allMembers, __ogen__)) { mixin("alias ",mem," = __ogen__.",mem,";"); } }; } class Tester { int add(int, int){return 0;} mixin(mixOverloadGen); } ``` The problem doing that is that I can have access to `__ogen__`, which makes code like that valid: `tester.__ogen__.add`. I can't make `private mixin OverloadGen __ogen__`, because I won't be able to publicly access my overloads. And doing `static foreach(mem; mixin OverloadGen)` is also invalid, tried with allMembers, so, this is my current solution, the other thing I could do is instead of aliasing to the mixin members, I could make them private and declare a public function inside my string mixin which calls those, which is just wasteful: increase compile time, runtime usage and code complexity.
Re: null == "" is true?
On Tuesday, 12 July 2022 at 16:40:38 UTC, H. S. Teoh wrote: On Tue, Jul 12, 2022 at 04:27:44PM +, Antonio via Digitalmars-d-learn wrote: It works ```d void main() { assert(null==""); } ``` why? Because an empty string is, by default, represented by an empty slice of the null pointer. Do not rely on this, however; it's possible sometimes to get an empty string that isn't null, e.g., if you incrementally shrink a slice over a string until it's empty. In that case, .ptr will not be null, but the string will still be empty. Always compare strings against "" rather than null, because the latter may not do what you think it does sometimes. T Yup, always compare the string with "". I have had this kind of problem a bunch of times, comparing it with null but it is not actually null
How to debug thread code
I'm stuck in a racing condition right now and I'm unable to run a debugger on the code. Usually I was using Visual Studio 2019 for debugging my code, but it shows the following message: "Your app has entered a break state, but there is no code to show because all threads were executing external code (typically system or framework code)." I can only access the main thread code which stops on my semaphore
Re: Improve a simple event handler
On Sunday, 16 January 2022 at 20:01:09 UTC, JN wrote: On Saturday, 15 January 2022 at 23:15:16 UTC, JN wrote: Is there some way I could improve this with some D features? My main gripes with it are: Managed to dramatically simplify it to 10 lines of code with variadic templates. ```d import std.stdio; struct Event(T...) { void function(T)[] listeners; void addListener(void function(T) handler) { listeners ~= handler; } void emit(T args) { foreach (listener; listeners) { listener(args); } } } void onResize(uint newWidth, uint newHeight) { writefln("Resized: %d %d", newWidth, newHeight); } void main() { Event!(uint, uint) windowResizeEvent; windowResizeEvent.addListener(&onResize); windowResizeEvent.emit(1000, 2000); } ``` I am very happy with this solution. My advice is to make your listeners return a boolean. This boolean is used to basically stop propagating the event. And debugging it seems really hard to be honest, so, incrementing it a little, I would do: ```d struct ListenerInfo { string name; string file; uint line; string registeredAt; } struct Event(T...) { bool function(T)[] listeners; ListenerInfo[] info; void addListener(bool function(T) handler, string name, string file = __FILE__, uint line = __LINE__, string registeredAt = __PRETTY_FUNCTION__) { listeners~= handler; info~= ListenerInfo(name, file, line, registeredAt); } void emit(T args) { foreach(i, l; listeners) { if(l(args)) { writeln(info[i]); break; } } } } ``` You could even extend this concept further by making it return an enum value for actually removing the listener when executed, stopping propagation. Or you could have access to the listener info inside the arguments too.
Re: Debug symbols from libs not being linked on windows
On Wednesday, 19 January 2022 at 02:31:31 UTC, Hipreme wrote: I have separated my project in a bunch of modules to be compiled separated. But it seems I have lost my debugging power since then. I would like to know if there is any workaround beside not using it as a lib. I'm using it from dub and it is has the debug options on them: ``` "buildOptions": [ "debugMode", "debugInfo", "debugInfoC" ], ``` And on every lib too. I had some errors about "duplicate object file, linking without debug info", an error that really should not exist as D works in modules. But I have renamed the necessary modules for getting rid of that message. After that, the problem was fixed by doing `dub clean --all-packages`, thanks rikki!
Re: Throw stack trace from program kill
On Sunday, 16 January 2022 at 18:03:53 UTC, Paul Backus wrote: On Sunday, 16 January 2022 at 15:15:07 UTC, Hipreme wrote: Is there some way to throw a stack trace when killing the program from the CTRL+C from the terminal? It would help a lot into debugging occasional infinity loops On POSIX, you can use the `sigaction` function to install a signal handler for `SIGINT`, the signal generated by CTRL+C. To terminate the program with a stack trace, simply have the signal handler `throw` an `Error`. Here's an example program that demonstrates the technique: ```d import core.sys.posix.signal; extern(C) void handleCtrlC(int) { throw new Error("Killed by CTRL+C"); } void main() { sigaction_t act = { sa_handler: &handleCtrlC }; int errcode = sigaction(SIGINT, &act, null); f(); // call some functions } void f() { g(); } void g() { h(); } void h() { while (1) {} // wait for ctrl+c } ``` Make sure to compile with the `-g` option if you want your stack trace to have filenames and line numbers. ```d import std.stdio; version(Posix) { import core.sys.posix.signal; extern(C) void handleCtrlC(int) { throw new Error("Killed by CTRL+C"); } bool setupSignal() { sigaction_t act = {sa_handler: &handleCtrlC}; int errCode = sigaction(SIGINT, &act, null); return errCode == 0; } } else version(Windows) { import core.sys.windows.windef; import core.sys.windows.wincon; extern(Windows) BOOL handleCtrlC(DWORD dwType) { switch(dwType) { case CTRL_C_EVENT: throw new Error("Killed by CTRL+C"); break; case CTRL_BREAK_EVENT: throw new Error("Killed by break"); break; default: throw new Error("Killed by unknown event"); break; } return TRUE; } bool setupSignal() { return SetConsoleCtrlHandler(cast(PHANDLER_ROUTINE)&handleCtrlC, TRUE) == TRUE; } } else{bool setupSignal(){return false;}} void a(){b();} void b(){c();} void c(){for(;;){}} void main(string[] args) { if(!setupSignal) writeln("Could not setup signal, exiting."); else a(); } ``` This is my current solution. The problem is that on Windows, it actually has the stack trace: ``` 0x76909A63 in CtrlRoutine 0x76BD6359 in BaseThreadInitThunk 0x76FF7B74 in RtlGetAppContainerNamedObjectPath 0x76FF7B44 in RtlGetAppContainerNamedObjectPath ``` If I throw that error on the Ctrl, it actually shows a message box: `The exception unknown software exception (0xe0441) occurred in the application at location: ...` Maybe there is some specific formatting for throwing exceptions to Windows recognize it?
Re: Function prototype overloading does not work ?
On Wednesday, 19 January 2022 at 08:47:27 UTC, Enjoys Math wrote: ``` module expr; import dots; import operator; import equation; import var; import var_expr; import zz_const; class Expr { public: void opBinary(string op)(string s) const { static if (op == "+") { Expr right = null; if (s == ".." || s == "..." || s == "") { right = new Dots(); } if (right !is null) return new Op("+", [this, right]); } } override string toString() const { assert(0); } Expr sub(Expr x, Expr y) { if (this == x) return y; return this; } Expr sub(Expr x, ref Var y) { return sub(x, new VarExpr(y)); } Expr sub(ref Var x, Expr y) { return sub(new VarExpr(x), y); } Expr sub(int x, Expr y) { return sub(ZZ(x), y); } Expr sub(Expr x, int y) { return sub(x, ZZ(y)); } Expr sub(ref Var x, ref Var y) { return sub(new VarExpr(x), new VarExpr(y)); } Expr sub(ref Var x, int y) { return sub(new VarExpr(x), ZZ(y)); } Expr sub(int x, ref Var y) { return sub(ZZ(x), new VarExpr(y)); } override bool opEquals(Object o) { return this is o; } } ``` See all the overloads I had to make to sub in order to bypass identity assignment for classes. I.e. Var can't be of type Expr. Anyway, this approach is not working because code calling `Expr.sub(int, Var)` is not seeing the definitions. It says no function matching those args, but clearly there are! Firstly, in my opinion, you should be using `auto ref` which will do the same thing as generating by reference and by value declarations. Or you could even use `in` as the compiler will optimize the call for passing it by reference. Now, you could have some self contained example for we being able to test it
Debug symbols from libs not being linked on windows
I have separated my project in a bunch of modules to be compiled separated. But it seems I have lost my debugging power since then. I would like to know if there is any workaround beside not using it as a lib. I'm using it from dub and it is has the debug options on them: ``` "buildOptions": [ "debugMode", "debugInfo", "debugInfoC" ], ``` And on every lib too.
Throw stack trace from program kill
Is there some way to throw a stack trace when killing the program from the CTRL+C from the terminal? It would help a lot into debugging occasional infinity loops
Re: Dynamically binding to D code using extern(D)
Okay, I do agree with you that I may have exaggerated with absolute intuitiveness, but I was talking about that intuitiveness for loading a symbol from a shared library. You're limited to using C's types - I think I don't understood what you meant with that, if the data type is known before head, it is possible to just declare it from the other side On Thursday, 30 September 2021 at 22:30:30 UTC, jfondren wrote: - you can't use overloading, lazy parameters, default values; you can't rely on scope parameters, etc., etc. - That seems to be pretty much more a problem for dynamically loading a function, although default values can be mirrored to in D API. - you can't casually hand over GC-allocated data and expect the other side to handle it right, or structs with lifetime functions that you expect to be called - That is another problem that doesn't seem related to the external linkage too, handling GC-allocated data with extern(D) doesn't stop it from it being garbage collected, I'm fixing that kind of error right now again. separate applications and some form of interprocess communication (pipes, unix sockets, TCP sockets) instead of function calls. - I'm pretty interested in how to make that thing work, but I think that would change a lot in how I'm designing my code, and with that way, it would probably become absolutely data oriented, right?
Dynamically binding to D code using extern(D)
I write this post as both a learning tool, a question and an inquiry. There are just a lot of drawbacks in trying to do function exporting while using D. That interface is absurdly confuse and that is probably why I've never seen a project here which made an use of extern(D) while using a DLL. While I'm making my DLL's generation, there are a lot of pitfalls that I can feel into. **Simple Function** ``` module something; extern(D) export int sum(int a, int b){return a + b;} ``` The correct way to bind to that function would be: ``` module app; import core.demangle int function(int a, int b) sum; void main() { sum = cast(typeof(sum))GetProcAddress(someDll, mangleFunc!(typeof(sum)("something.sum"); } ``` And that should be it for loading a simple function. Now, lets make our case a bit more complicated: **Overloaded function** ``` module something; extern(D) export int add(int a, int b) { return a + b; } extern(D) export float add(float a, float b) { return a+b; } ``` For loading those functions, the correct way would be ``` module app; import core.demangle; int function(int a, int b) sumInt; float function(float a, float b) sumFloat; int sum(int a, int b){return sumInt(a, b);} float sum(float a, float b){return sumFloat(a,b);} void main() { sumInt = cast(typeof(sumInt))GetProcAddress(dll, mangleFunc!(typeof(sumInt))("something.sum")); sumFloat = cast(typeof(sumFloat))GetProcAddress(dll, mangleFunc!(typeof(sumFloat))("something.sum")); } ``` Notice how much the overall complexity starts to increase as there seems to be no way to put get the overloads and there doesn't seem to be any advantage in using extern(D). **Static Methods** The only difference from the default functions is that we need to pass the class name as a module name. **Static Methods returning user data** That is mainly the reason I'm writing that post. It made me really wonder if I should really use extern(D). This section will use 3 files because after all, there is really a (consistency?) problem ``` module supertest; import ultratest; class SuperTest { extern(D) export static SuperTest getter(){return new SuperTest();} extern(D) export static UltraTest ultraGetter(){return new UltraTest();} import core.demangle; pragma(msg, mangleFunc!(typeof(&SuperTest.getter))("supertest.SuperTest.getter")); //Prints _D9supertest9SuperTest6getterFZCQBeQx pragma(msg, mangleFunc!(typeof(&SuperTest.ultraGetter))("supertest.SuperTest.ultraGetter")); //Prints _D9supertest9SuperTest11ultraGetterFZC9ultratest9UltraTest } ``` ``` module ultratest; class UltraTest{} ``` ``` module app; import core.demangle; void main() { //??? } ``` As you can see at module supertest, the pattern seems to break when returning user data for another module. From my knowledge, I don't know how could I get this function, specially because you will need to know: the module that you're importing the function + the module that where the userdata is defined for getting it. It seems pretty insane to work with that. extern(D) advantages: - extern(D) disadvantages: - Code only callable in D(probably no other language as a demangler) - I don't remember seeing any other code before in that post doing that, so, no documentation at all - You will need to call the demangler for binding to a symbol, which in my project, it could make each call to a unique type from the demangler costs 15KB - You will need to know the module which you imported your function - If your function returns userdata from another function, there doesn't seem to be any workaround - Doesn't provide any overloading binding support though the language has support to overloading extern(C) advantages: - Code callable from any language as it is absolutely intuitive - Well documented extern(C) disadvantages: - You will need to declare your function pointer as extern(C) or it will swap the arguments order. I have not even entered in the case where I tried overloading static methods, which I think it would need to declarate aliases to the static methods typings for actually generating a mangled name. I want to know if extern(D) is actually meant to not be touched. adr said that his use for that was actually when doing extern(C): //Funcs defined here extern(D): //Resets the linkage to the default one So, there are just too many disadvantages for doing extern(D) for binding it to any code, I would like to know where we can get more documentation than what I posted here right now (really, I've never saw any code binding to an extern(D) code). And I do believe that is the main reason why people usually don't use dynamic libs in D, it is just inviable as you would need to regenerate all the API yourself
Re: 0 cost template instantiation
On Thursday, 30 September 2021 at 03:21:51 UTC, jfondren wrote: On Thursday, 30 September 2021 at 03:13:28 UTC, jfondren wrote: As provided, loadSymbol without the "static if": 965K libhipengine_api.a with `mixin(loadSymbol("name"))` instead of a template: 749K libhipengine_api.a The difference goes down to 66K vs. 60K with `dub -brelease --compiler=gdc`. ldc's not as slim but still much better than dmd, and -brelease is actually much less significant. So dmd's the main culprit for the bloat here. huh. But since you have importPaths-ldc perhaps you weren't using dmd to begin with. Yup. The mixin(loadSymbol("")) seems the best way to do. I believe that should be the option for loading separated symbols while loadSymbols version is the best for loading a lot of symbols(IDK how expensive is mixing a lot of functions) as it costs 1KB per instantiation. I'm actually using DMD and LDC, dmd compiles a bit faster, but I use ldc for deploying it. Never used GDC.
Re: 0 cost template instantiation
On Thursday, 30 September 2021 at 02:22:35 UTC, jfondren wrote: On Thursday, 30 September 2021 at 01:44:57 UTC, jfondren wrote: On Thursday, 30 September 2021 at 01:09:47 UTC, Hipreme wrote: I have a template function that all it does is given a symbol, it loads a dll for its type + its name: ``` void loadSymbol(alias s, string symName = "")() { static if(symName == "") s = cast(typeof(s))_loadSymbol(_dll, (s.stringof~"\0").ptr); else s = cast(typeof(s))_loadSymbol(_dll, (symName~"\0").ptr); } ``` If symName is always a string literal, then you don't need to append a "\0"; string literals always have a trailing NUL after them, and they autoconvert to const(char)[] so you don't need the .ptr either. Playing around with this, with a mock-up of your code, doesn't change object size at all. Is the actual source available, that you're seeing this with? https://github.com/MrcSnm/HipremeEngine/tree/hotload/api You may try messing at the module api.graphics.g2d.renderer2d There is a function called initG2D Try changing it from loadSymbols to each one loadSymbol. You can just dub at the folder api.
Re: 0 cost template instantiation
On Thursday, 30 September 2021 at 01:09:47 UTC, Hipreme wrote: I have a template function that all it does is given a symbol, it loads a dll for its type + its name: ``` void loadSymbol(alias s, string symName = "")() { static if(symName == "") s = cast(typeof(s))_loadSymbol(_dll, (s.stringof~"\0").ptr); else s = cast(typeof(s))_loadSymbol(_dll, (symName~"\0").ptr); } ``` The main problem is that this function is costing 2KB per instantiation, which is something pretty high. Specially if I inline, there is almost no cost when compared to its inline version. Trying to use pragma(inline, true) didn't do anything too. If I understood correctly, mixin template would be some way to actually inline anything. The problem is that I can't have any kind of expression inside it, so, that's the only way I could think in how to do it. Optimization seems to don't take care of that behaviour too. I would like to know which approach could I take for making something like C's #define for that. As this function could be really rewritten as a macro if I were coding in C, the cost is too high for a function that would be only a syntactic sugar I could reduce by almost 100kb of code by instead of using the former option, I use: ``` void loadSymbols(Ts...)() { static foreach(s; Ts) s = cast(typeof(s))_loadSymbol(_dll, s.stringof); } ``` Then instead of making a call for each one, I just pass a list of templates, this would only create one instantiation per need. I do still don't think that this should be the answer, as the alias problem is not yet solved. It takes a lot of size for functions that could be only syntactic sugar, where C would be a lot better
Re: 0 cost template instantiation
On Thursday, 30 September 2021 at 01:56:42 UTC, Basile B. wrote: On Thursday, 30 September 2021 at 01:09:47 UTC, Hipreme wrote: I have a template function that all it does is given a symbol, it loads a dll for its type + its name: ``` void loadSymbol(alias s, string symName = "")() { static if(symName == "") s = cast(typeof(s))_loadSymbol(_dll, (s.stringof~"\0").ptr); else s = cast(typeof(s))_loadSymbol(_dll, (symName~"\0").ptr); } ``` The main problem is that this function is costing 2KB per instantiation, which is something pretty high. Specially if I inline, there is almost no cost when compared to its inline version. Trying to use pragma(inline, true) didn't do anything too. cant you just use a regular functions ? loading happens at runtime right ? The entire reason to having that function is having that syntax which would pretty much do the monkey's job for me: Instead of writing myFunction = cast(typeof(myFunction))_loadSymbol(_dll, "myFunction"); I could write loadSymbol!myFunction; But if no other way is found of doing that, I will do the massive rewriting. Anyway, I don't think the problem is not in the way I'm doing, but the output, as that template could easily be inlined
0 cost template instantiation
I have a template function that all it does is given a symbol, it loads a dll for its type + its name: ``` void loadSymbol(alias s, string symName = "")() { static if(symName == "") s = cast(typeof(s))_loadSymbol(_dll, (s.stringof~"\0").ptr); else s = cast(typeof(s))_loadSymbol(_dll, (symName~"\0").ptr); } ``` The main problem is that this function is costing 2KB per instantiation, which is something pretty high. Specially if I inline, there is almost no cost when compared to its inline version. Trying to use pragma(inline, true) didn't do anything too. If I understood correctly, mixin template would be some way to actually inline anything. The problem is that I can't have any kind of expression inside it, so, that's the only way I could think in how to do it. Optimization seems to don't take care of that behaviour too. I would like to know which approach could I take for making something like C's #define for that. As this function could be really rewritten as a macro if I were coding in C, the cost is too high for a function that would be only a syntactic sugar
D's dll and classes
I have a plenty of questions related to the DLL things, .di files. Basically: I have a main program which would contain a lot of code. I have a secondary program which I want to call code from the main program, but it will be compiled as a DLL to the main program call a single entry point from that DLL. I have been able to call that secondary okay, the problem is that the main is linked into the secondary in order to call the main program code. That causes problems related to initialization (as only the main should care) and a big binary size. I tried writing only .di file for it, but then it would only get undefined symbol. What I expected is: A constains code A.di contains interfacing code B uses A.di interfacing code B is compiled as a DLL A loads B A calls B