Re: How to load a DLL file in D?
On Saturday, 11 May 2024 at 20:04:38 UTC, Lance Bachmeier wrote: On Saturday, 11 May 2024 at 19:33:03 UTC, solidstate1991 wrote: I know that BindBC exists and otherwise would use it, but the bigger the library, the more extra hurdle it'll have. When I did a few bindings with it, I had to order the functions the right way, so I could do things much quicker with the Ctrl+Alt+Shift trick under VSCode, and even then having to write both a statically linked and dynamically linked version (the latter which required the functions to be loaded individually into function pointers). Maybe I should write some automation tool... You might find this package useful https://code.dlang.org/packages/dynamic Also relevant if they're C functions: https://forum.dlang.org/post/qxctappnigkwvaqak...@forum.dlang.org And this if you want to convert C headers to D code: https://forum.dlang.org/post/ugvc3o$5t3$1...@digitalmars.com
Re: How to load a DLL file in D?
On Saturday, 11 May 2024 at 19:33:03 UTC, solidstate1991 wrote: I know that BindBC exists and otherwise would use it, but the bigger the library, the more extra hurdle it'll have. When I did a few bindings with it, I had to order the functions the right way, so I could do things much quicker with the Ctrl+Alt+Shift trick under VSCode, and even then having to write both a statically linked and dynamically linked version (the latter which required the functions to be loaded individually into function pointers). Maybe I should write some automation tool... You might find this package useful https://code.dlang.org/packages/dynamic
Re: D DLL crashes if not run on the main thread
Assuming it works outside of a DLL, you're probably missing the runtime initialization calls. Mix SimpleDllMain in (or do your own). https://github.com/dlang/dmd/blob/9639d72ea0883808feff7aba71d87c5a78fb7f92/druntime/src/core/sys/windows/dll.d#L577
Re: D DLL crashes if not run on the main thread
On Tuesday, 5 September 2023 at 22:53:35 UTC, Richard (Rikki) Andrew Cattermole wrote: Whatever is going on, that function you showed would not call into druntime. So I don't think it's related. As of right now I have no tips as I'm tired, but I suspect its on the .net end. Sorry for the confusion, that function actually runs fine and it was something completely unrelated that caused the crash. However, swapping that out for a function that does interact with the druntime does cause a crash (it calls a function template inside of a class and returns the value)
Re: D DLL crashes if not run on the main thread
On Tuesday, 5 September 2023 at 22:45:28 UTC, raven09 wrote: I *assume* that this has something to do with D's GC? But I tried calling GC.disable() and nothing changed. Any help or insight would be appreciated. Thanks in advance If you want to have a D DLL called from elsewhere, and don't control which threads call your dynlib: - first thread that comes (or the DLL load itself) should initialize the runtime. You can use pragma(crt_destructor) to deinitialize the D runtime. - threads that come through a callback should in general register to the D runtime, and unregister on exit. They will not hold roots while they are back in C land, and you must unregister them on exit else the GC will try to pause possibly dead threads when it collects. You can leave some threads unregistered, but then I'm not sure for TLS and they certainly cannot hold GC roots. You can also leave the whole D runtime disabled, but that is annoying (no GC, amongst other things).
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.
Re: D DLL crashes if not run on the main thread
Whatever is going on, that function you showed would not call into druntime. So I don't think it's related. As of right now I have no tips as I'm tired, but I suspect its on the .net end.
D DLL crashes if not run on the main thread
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. I *assume* that this has something to do with D's GC? But I tried calling GC.disable() and nothing changed. Any help or insight would be appreciated. Thanks in advance
Re: How static link dll msvcr120.dll?
On Thursday, 1 June 2023 at 15:05:40 UTC, Marcone wrote: I linked msvcr120.lib, but the executable still ask for msvcr120.dll not found. i am sorry. my words was sourced from common sence, usual practice. it seems, msvcr120 is special case, and have only one version of .lib - for link to .dll i cant find static lib for msvcr120 :(
Re: How static link dll msvcr120.dll?
On Thursday, 1 June 2023 at 15:05:40 UTC, Marcone wrote: I linked msvcr120.lib, but the executable still ask for msvcr120.dll not found. msvcr120.lib is a "link library", not a static library. On other systems, you pass shared libraries directly to the linker and it will pull the information it needs from there to set up the exectuable with what it needs for the system loader to load the shared library at runtime. Windows works differently. The compiler puts all that information in a link library when it creates the DLL, and you pass that to the linker instead of the DLL. Windows system libraries are not distributed as static libraries as far as I know.
Re: How static link dll msvcr120.dll?
On Tuesday, 30 May 2023 at 05:18:11 UTC, novice2 wrote: you cannot "static link dll", "d" in "dll" is "dynamic". you can implicity or explicity load dll. https://learn.microsoft.com/en-us/cpp/build/linking-an-executable-to-a-dll?view=msvc-170 may be you mean static link msvcr120.lib? i am not windows guru, but you need msvcr120.lib (there is 2 version of .lib - one small for use .dll and contain only reference to code in dll, other large, for static linking, contains all code). to link mylib.lib you can use pragma(lib, "mylib.lib") in D code. I linked msvcr120.lib, but the executable still ask for msvcr120.dll not found.
Re: How static link dll msvcr120.dll?
you cannot "static link dll", "d" in "dll" is "dynamic". you can implicity or explicity load dll. https://learn.microsoft.com/en-us/cpp/build/linking-an-executable-to-a-dll?view=msvc-170 may be you mean static link msvcr120.lib? i am not windows guru, but you need msvcr120.lib (there is 2 version of .lib - one small for use .dll and contain only reference to code in dll, other large, for static linking, contains all code). to link mylib.lib you can use pragma(lib, "mylib.lib") in D code.
Re: How static link dll msvcr120.dll?
On Friday, 26 May 2023 at 12:29:15 UTC, Marcone wrote: How can I static link msvcr120.dll using dmd? Please, could someone tell me if it is possible to link the msvcr120.dll library to the program's executable using the dmd compiler? Because I would like my program to remain portable.
How static link dll msvcr120.dll?
How can I static link msvcr120.dll using dmd?
Re: Is it possible to make a library (dll/so) from separated .d files?
On Monday, 3 April 2023 at 11:29:12 UTC, Hipreme wrote: 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++. https://github.com/MrcSnm/HipremeEngine/blob/66618c7783d62107bcaad393d5af5b86c9387b34/api/source/hip/api/package.d#L58 Thank you, looks almost what I need!
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: 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? There are examples of code here https://docs.unrealengine.com/5.1/en-US/unreal-engine-for-unity-developers/
Is it possible to make a library (dll/so) from separated .d files?
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?
Re: compile x64 .dll and .so without dependencies
On Sunday, 5 March 2023 at 18:35:58 UTC, Guillaume Piolat wrote: "targetType": "dynamicLibrary", "dflags-linux-dmd": ["-defaultlib=libphobos2.a"], "dflags-osx-ldc": ["-static"], "dflags-linux-ldc": ["-link-defaultlib-shared=false"], "dflags-linux-x86_64-ldc": ["-fvisibility=hidden"], "dflags-windows-ldc": ["-mscrtlib=libcmt","-fvisibility=hidden", "-link-defaultlib-shared=false"], Additionally on (Windows + DUB + LDC), you will need to set an envvar: DFLAGS=-fvisibility=hidden -dllimport=none Thank you!
Re: compile x64 .dll and .so without dependencies
On Sunday, 5 March 2023 at 06:36:05 UTC, novice2 wrote: It there any recipe to compile x64 .dll without dependencies? I mean it shoud be used without installing things like msvcr120.dll. Dependencies on system dll (advapi32.dll, kerner32.dll) is ok. I don't experiment on linux yet. But interest too. What we do here in dub.json, for no deps on big 3 desktop OSes: "targetType": "dynamicLibrary", "dflags-linux-dmd": ["-defaultlib=libphobos2.a"], "dflags-osx-ldc": ["-static"], "dflags-linux-ldc": ["-link-defaultlib-shared=false"], "dflags-linux-x86_64-ldc": ["-fvisibility=hidden"], "dflags-windows-ldc": ["-mscrtlib=libcmt","-fvisibility=hidden", "-link-defaultlib-shared=false"], Additionally on (Windows + DUB + LDC), you will need to set an envvar: DFLAGS=-fvisibility=hidden -dllimport=none else you may still depend upon a dynamic phobos. It's unfortunate situation for such a common requirement...
compile x64 .dll and .so without dependencies
It there any recipe to compile x64 .dll without dependencies? I mean it shoud be used without installing things like msvcr120.dll. Dependencies on system dll (advapi32.dll, kerner32.dll) is ok. I don't experiment on linux yet. But interest too.
Re: Dub is not finding the dynamic link library MSVCR120.dll...
On Monday, 20 February 2023 at 01:04:25 UTC, Mike Parker wrote: Any error about a missing DLL is a run-time error that's unrelated to dub or the compiler. Normally, for end users, a missing MSVC runtime DLL means you have to install the MSVC Redistributable package. This version of the DLL you're missing is from MSVC 2013, so that's the version of the package you'd need. However, I wonder what's causing the problem in the first place. Do you have Visual Studio installed, or are you using the out-of-the-box libraries and linker that ship with DMD? Thanks for setting me straight. I'm trying to make D application that you can just download and start up. Hopefully with having to install D first or the DLL. I see that msvc120.dll is in the same directory as dmd.exe.and dub.exe.
Re: Dub is not finding the dynamic link library MSVCR120.dll...
On Sunday, 19 February 2023 at 21:05:33 UTC, WhatMeWorry wrote: and is abending with an error saying exactly this. How do I specify the path to this library? Can I use one of the environment variables in sc.ini, one of the Windows env variables, or one of the dub options? Btw, I'm bypassing on purpose the official D installation. Any error about a missing DLL is a run-time error that's unrelated to dub or the compiler. Normally, for end users, a missing MSVC runtime DLL means you have to install the MSVC Redistributable package. This version of the DLL you're missing is from MSVC 2013, so that's the version of the package you'd need. However, I wonder what's causing the problem in the first place. Do you have Visual Studio installed, or are you using the out-of-the-box libraries and linker that ship with DMD?
Dub is not finding the dynamic link library MSVCR120.dll...
and is abending with an error saying exactly this. How do I specify the path to this library? Can I use one of the environment variables in sc.ini, one of the Windows env variables, or one of the dub options? Btw, I'm bypassing on purpose the official D installation.
Re: betterC DLL in Windows
On Monday, 6 February 2023 at 15:54:40 UTC, bachmeier wrote: This is the specification for the D Programming Language. I've been bitten by that a few times over the years, though to be honest, I'm not sure of the relationship of the spec to documentation. The Phobos documentation and compiler documentation appear to be actual documentation, in the sense that you can trust it to be accurate, and if not it's a bug. I see... I guess I was confused by the title of the link, "Language Reference" on the Docs page, and didn't look carefully at the URL or the text after that.
Re: betterC DLL in Windows
On Sunday, 5 February 2023 at 19:00:16 UTC, Richard (Rikki) Andrew Cattermole wrote: So LDC with druntime and yes GC turned on is good enough right now that you can probably make it work without too much effort. You don't necessarily have to limit yourself to -betterC. In fact if you don't, you have access to PyD[0] which can handle the interop stuff for you. I haven't personally used it, but it might work for your use case :) [...] But yeah if you can avoid having to create bindings for stuff (such as glib which we have bindings for), or wrappers ext. do so. That way you can do more of the fun things! Sounds quite convincing, I think I might do it this way, instead of with betterC. Not needing additional python bindings does sound like a big plus. Thanks.
Re: betterC DLL in Windows
On Mon, Feb 06, 2023 at 03:54:40PM +, bachmeier via Digitalmars-d-learn wrote: > On Sunday, 5 February 2023 at 08:48:34 UTC, Tamas wrote: [...] > > This is the specification for the D Programming Language. > > I've been bitten by that a few times over the years, though to be > honest, I'm not sure of the relationship of the spec to documentation. > The Phobos documentation and compiler documentation appear to be > actual documentation, in the sense that you can trust it to be > accurate, and if not it's a bug. Maybe someone that has been around > from the earliest days understands the goal of the spec. IIRC the spec was started as part of an ongoing effort to fully specify the language so that, at least in theory, someone could read the spec and implement a D compiler completely independent of the current ones. T -- INTEL = Only half of "intelligence".
Re: betterC DLL in Windows
On Sunday, 5 February 2023 at 08:48:34 UTC, Tamas wrote: I appreciate all of this... however, as a newcomer, I wish the docs were simply more honest, instead of representing wishful thinking. I guess in any programming language, experience reveals things not present in the docs, but it seems to apply much more acutely here. Technically, those pages are [the spec rather than documentation](https://dlang.org/spec/spec.html). This is the specification for the D Programming Language. I've been bitten by that a few times over the years, though to be honest, I'm not sure of the relationship of the spec to documentation. The Phobos documentation and compiler documentation appear to be actual documentation, in the sense that you can trust it to be accurate, and if not it's a bug. Maybe someone that has been around from the earliest days understands the goal of the spec.
Re: betterC DLL in Windows
On 05/02/2023 10:01 PM, Tamas wrote: On the surface, betterC seems to be perfect for this case. How would YOU do it (Adam, Richard)? BtW, gstreamer also has D bindings, and maybe in the future I'll use those. I suspect that Adam's suggestions have a stronger relevance to that case, right? So LDC with druntime and yes GC turned on is good enough right now that you can probably make it work without too much effort. You don't necessarily have to limit yourself to -betterC. In fact if you don't, you have access to PyD[0] which can handle the interop stuff for you. I haven't personally used it, but it might work for your use case :) The main thing is no matter what flags you pass, you'll need to be careful about memory ownership between the language divide and the ownership therein. You have already got a hang of that though from the C version! Just gotta be extra careful with GC memory that its pinned on the D side and won't get free'd elsewhere. But yeah if you can avoid having to create bindings for stuff (such as glib which we have bindings for), or wrappers ext. do so. That way you can do more of the fun things! [0] https://github.com/ariovistus/pyd
Re: betterC DLL in Windows
On Sunday, 5 February 2023 at 00:27:19 UTC, Richard (Rikki) Andrew Cattermole wrote: On 05/02/2023 1:20 PM, Adam D Ruppe wrote: Even module imports can fail because betterC disables outputting the module data info, even if it would otherwise be required by language rules, despite it not using the druntime. This only affects you if you use full D to interact with -betterC code. Even then it is very easy to work around. https://github.com/Project-Sidero/basic_memory/blob/main/source/sidero/base/moduleinfostubs.d -betterC DLL's do work with full D executables. If all you need it for is gluing some stuff together don't listen to Adam about it not working, because it absolutely does and quite usable if you're not expecting there to be a GC. I'm repeating myself, but I'm very happy to see so many helpful responses to my newbie question. It gives me a good feeling about the community here. As I wrote, I'd like to use D only in a limited way, for now. My project actually interfaces Python and glib/gstreamer, the glue being provided by my C code. What I'd like to do is to improve on my C code, inspired by [this interview](https://dlang.org/blog/2017/08/23/d-as-a-better-c/). I don't want to introduce another GC or runtime into the picture, and I probably don't need to call any D libraries. Python -> my C code -> glib/gstreamer C libs to Python -> C improved by betterC -> glib/gstreamer C libs On the surface, betterC seems to be perfect for this case. How would YOU do it (Adam, Richard)? BtW, gstreamer also has D bindings, and maybe in the future I'll use those. I suspect that Adam's suggestions have a stronger relevance to that case, right?
Re: betterC DLL in Windows
On Sunday, 5 February 2023 at 00:20:24 UTC, Adam D Ruppe wrote: There's a lot of things described in the documentation that don't actually work. D can be an *extremely* productive language if you know which parts to focus on, but most the newer hyped features just don't deliver. The table of contents on the left side of the site is in roughly chronological order. The things near the top are pretty reliable, [...]. The things near the bottom are not reliable. [...] and so on I appreciate all of this... however, as a newcomer, I wish the docs were simply more honest, instead of representing wishful thinking. I guess in any programming language, experience reveals things not present in the docs, but it seems to apply much more acutely here.
Re: betterC DLL in Windows
On Saturday, 4 February 2023 at 19:44:15 UTC, bachmeier wrote: On Saturday, 4 February 2023 at 18:29:41 UTC, Tamas wrote: What's the reason to prefer LDC over DMD? Anyone that cares about performance will use LDC rather than DMD. It's hard to imagine a case where someone would want betterC to avoid the GC, but they wouldn't want to use LDC. When I started using D many years ago, LDC was behind DMD, so you needed to use DMD to have a current compiler. That's no longer true. The only reason I use DMD today is the faster compilation speed when I'm doing a lot of write-compile-debug iterations. Good to know, thank you. The posts I've seen so far online suggesting to start with DMD must've been outdated, then.
Re: betterC DLL in Windows
On Saturday, 4 February 2023 at 18:40:51 UTC, Tamas wrote: I do take your word for it, but now I have to re-evaluate my expectations towards D and perhaps use it for another project. I've got most of my project working in C already, but I was hoping to add some safety and better readability/managability by using some of the convenient features D offers over C. This is achieved without the betterC switch, and severely limited with it. Also, your words give me the impression that I cannot trust the documentation; which isn't a great start into the learning process. There's a lot of things described in the documentation that don't actually work. D can be an *extremely* productive language if you know which parts to focus on, but most the newer hyped features just don't deliver. The table of contents on the left side of the site is in roughly chronological order. The things near the top are pretty reliable, with a few exceptions (which are generally called out in the documentation if you read it carefully, like how the "static initialization of associative arrays" is "not yet implemented", or misuse of shared is "is not an error yet by default"). The things near the bottom are not reliable. The C++ interface works in some cases but you aren't likely to get far using it in any real world project; the C++ stdlib bindings are extremely minimal and Windows-only. The Objective-C interface works beautifully on dmd which cannot target the new Apple devices. ldc can generate code for those arm chips, but the Objective-C interface is not implemented on ldc. The portability guide and named character entities are pretty much ok. The memory safety `@safe` stuff only actually works if you 1) opt into it in the functions and 2) opt into it on command line params. This is mentioned in the docs as a small note near the bottom. The design of @safe also allows several things that can escape it on certain systems. The ABI page is ok, but there are several bugs in the debug info output. I find it good enough but it can be annoying. The vector extensions work on dmd if you can piece together the magic but the other compilers do it differently. The betterC page has several falsehoods on it, including the misinformation that you need to use it to link into C applications. This is just 100% nonsense. It also claims nearly the full language remains available, but this is also simply false. Some of the things listed there can be made to work with a bunch of code, but many things just plain don't work, even if you add the small amounts of code necessary to enable them. For example, interfaces don't work, even if you implement your own dynamic cast function. It just doesn't let them link. It claims constructors and destructors work, which is true, unless they're `static`, in which case you get random errors. Delegates and lambdas work if you manage captured variables in your own functors, but otherwise are simply disabled, even if you had your own backing system. Even module imports can fail because betterC disables outputting the module data info, even if it would otherwise be required by language rules, despite it not using the druntime. Then importC only works for toy examples. Using two separate headers or modules will result in spurious compile errors (and bugs detailing how to address this have been closed WONTFIX), and there's several kinds of C apis it just doesn't support. And finally, the @live functions also only work in toy examples and the design is fundamentally limited to only direct function calls, no struct aggregation is supported at all. It is a complete dead end. On the other hand, if you avoid most the compiler switches and stick to the more solid features - "Interfacing to C" and above on the list, for the most part - you'll find D is a very capable conservative language.
Re: betterC DLL in Windows
On 05/02/2023 1:20 PM, Adam D Ruppe wrote: Even module imports can fail because betterC disables outputting the module data info, even if it would otherwise be required by language rules, despite it not using the druntime. This only affects you if you use full D to interact with -betterC code. Even then it is very easy to work around. https://github.com/Project-Sidero/basic_memory/blob/main/source/sidero/base/moduleinfostubs.d -betterC DLL's do work with full D executables. If all you need it for is gluing some stuff together don't listen to Adam about it not working, because it absolutely does and quite usable if you're not expecting there to be a GC.
Re: betterC DLL in Windows
In betterC mode you don't have access to the standard library or the runtime You can only access the libc functions Basically the modules from: ``import core.stdc`` So for your example, just do like you'd do in C As simple as that As for DMD/LDC, easy: DMD: reference compiler, fast compile time LDC: LLVM based compiler, LLVM is slow, but provides great optimizations It's common to use DMD for debug, fast iteration time, and LDC for release builds, so you en enjoy great performance
Re: betterC DLL in Windows
On Saturday, 4 February 2023 at 19:49:41 UTC, bachmeier wrote: I'm not sure what Adam's getting at when he says "hopelessly broken" but it's basically a subset of D. You're almost guaranteed to hit some wall with it and have no solution. Some of these are bugs but some of them are by design; betterC is a set of arbitrary restrictions without much consistent reasoning behind them. For example, with dlls, you still have to deal with all the potential problems of C library version mismatches, but if you use any module that touches a D feature it is likely to compile but then fail to link when someone uses it! All pain, no gain.
Re: betterC DLL in Windows
On Saturday, 4 February 2023 at 18:40:51 UTC, Tamas wrote: It is hopelessly broken, but thankfully, it also brings zero benefit, so simply not using it is a viable path forward. I do take your word for it, but now I have to re-evaluate my expectations towards D and perhaps use it for another project. I've got most of my project working in C already, but I was hoping to add some safety and better readability/managability by using some of the convenient features D offers over C. And, of course, learn D in the process. Also, your words give me the impression that I cannot trust the documentation; which isn't a great start into the learning process. I'm not sure what Adam's getting at when he says "hopelessly broken" but it's basically a subset of D. The main reason I've seen people wanting betterC is to avoid the GC. Well, you don't need betterC for that, you use @nogc and then you don't have to worry about the GC. I mostly need interop with C libraries and D would only serve as a glue, so I don't really need several features like GC etc. Just don't call those functions and they won't hurt you, aside from adding ~200 KB of size to the dll. On the other hand, the -betterC switch is hurting you - as evidenced by your own attempt working until you added it. It can be evidence of something broken in D as you say (simplified) or of my lack of experience with D - a simple missing include, badly configured PATH, or lack of understanding on my part what SimpleDllMain does. I think the point is that it works without the betterC switch, so it's not your lack of experience that's the problem, it's the functionality that you lose when you use that switch.
Re: betterC DLL in Windows
On Saturday, 4 February 2023 at 18:29:41 UTC, Tamas wrote: What's the reason to prefer LDC over DMD? Anyone that cares about performance will use LDC rather than DMD. It's hard to imagine a case where someone would want betterC to avoid the GC, but they wouldn't want to use LDC. When I started using D many years ago, LDC was behind DMD, so you needed to use DMD to have a current compiler. That's no longer true. The only reason I use DMD today is the faster compilation speed when I'm doing a lot of write-compile-debug iterations.
Re: betterC DLL in Windows
On Saturday, 4 February 2023 at 18:27:34 UTC, Adam D Ruppe wrote: On Saturday, 4 February 2023 at 18:11:05 UTC, Tamas wrote: Well, as I'm new to D this isn't something I have insight into. Then you'd probably be better off taking my word for it (or even trusting your own limited experience where things worked until you added the switch) and just not using -betterC switch. It is hopelessly broken, but thankfully, it also brings zero benefit, so simply not using it is a viable path forward. I do take your word for it, but now I have to re-evaluate my expectations towards D and perhaps use it for another project. I've got most of my project working in C already, but I was hoping to add some safety and better readability/managability by using some of the convenient features D offers over C. And, of course, learn D in the process. Also, your words give me the impression that I cannot trust the documentation; which isn't a great start into the learning process. I mostly need interop with C libraries and D would only serve as a glue, so I don't really need several features like GC etc. Just don't call those functions and they won't hurt you, aside from adding ~200 KB of size to the dll. On the other hand, the -betterC switch is hurting you - as evidenced by your own attempt working until you added it. It can be evidence of something broken in D as you say (simplified) or of my lack of experience with D - a simple missing include, badly configured PATH, or lack of understanding on my part what SimpleDllMain does.
Re: betterC DLL in Windows
On 05/02/2023 7:29 AM, Tamas wrote: What's the reason to prefer LDC over DMD? DMD is currently a write off for DLL support (some things do work, but its very easy to hit situations that don't). I've been looking into this for the past year, implemented some things in dub to get it to work, also currently working on the redesign of export :)
Re: betterC DLL in Windows
On Saturday, 4 February 2023 at 16:51:36 UTC, Richard (Rikki) Andrew Cattermole wrote: You don't have access to druntime/Phobos stuff at runtime. SimpleDllMain is for initializing and uninitializing druntime. See: https://github.com/Project-Sidero/basic_memory/blob/main/source/sidero/base/dllmain.d You want to only use ldc atm. The defaults right now should most likely "just work" in dub for a single compile + link step (i.e. only a single static library in dll). If you do it manually, you'll want to add the flag ``--fvisibility=public`` to export everything. I'm not sure I understand every bit of it yet, but this looks helpful, thank you. I was able to compile this (based on dllmain.d linked by you) with both DMD and LDC: ```D module WindowsApp1; version (Windows) { version (D_BetterC) { import core.sys.windows.windef : HINSTANCE, BOOL, DWORD, LPVOID; extern (Windows) BOOL DllMain(HINSTANCE hInstance, DWORD ulReason, LPVOID reserved) { return true; } } else { import core.sys.windows.dll; mixin SimpleDllMain; } } export extern (C) void foo() { import core.stdc.stdio : printf; printf("Hello betterC\n"); } ``` What's the reason to prefer LDC over DMD?
Re: betterC DLL in Windows
On Saturday, 4 February 2023 at 18:11:05 UTC, Tamas wrote: Well, as I'm new to D this isn't something I have insight into. Then you'd probably be better off taking my word for it (or even trusting your own limited experience where things worked until you added the switch) and just not using -betterC switch. It is hopelessly broken, but thankfully, it also brings zero benefit, so simply not using it is a viable path forward. I mostly need interop with C libraries and D would only serve as a glue, so I don't really need several features like GC etc. Just don't call those functions and they won't hurt you, aside from adding ~200 KB of size to the dll. On the other hand, the -betterC switch is hurting you - as evidenced by your own attempt working until you added it. Perhaps, but this doesn't help me much. It is a very easy solution to your problem. It is up to you if you want to take it and continue on in productivity or keep suffering for no benefit (and you'll find more trouble the further you go using the broken, barely supported switch).
Re: betterC DLL in Windows
Hi, thanks for the feedback. I'm happy to see 2 replies so quickly. On Saturday, 4 February 2023 at 17:26:17 UTC, Adam D Ruppe wrote: On Saturday, 4 February 2023 at 16:45:31 UTC, Tamas wrote: export extern (C) void main() mixin SimpleDllMain; No need to ever mix two mains together, the DllMain is the required one. Indeed, that is an oversight on my part. However, that's just a typo I happened to include in my last attempt. I use foo() and others, and .def exporting them etc. Tried various things based on the examples I linked. and they compile without `-betterC`, but fail with link errors when using the switch. then don't use the switch lol -betterC is barely supported and completely useless so better to just not use it. Well, as I'm new to D this isn't something I have insight into. However, this being and advertised feature of the language, I'm surprised to see that you dismiss it so casually. Also, for my project, I mostly need interop with C libraries and D would only serve as a glue, so I don't really need several features like GC etc. `betterC`, at least what I thought it was supposed to be, seemed to be a good fit for what I need. error LNK2019: unresolved external symbol _D4core3sys7windows3dll18dll_process_attachFPvbZb referenced in function DllMain This is just betterC breaking the code. Perhaps, but this doesn't help me much.
Re: betterC DLL in Windows
On Saturday, 4 February 2023 at 16:45:31 UTC, Tamas wrote: and they compile without `-betterC`, but fail with link errors when using the switch. then don't use the switch lol -betterC is barely supported and completely useless so better to just not use it. export extern (C) void main() mixin SimpleDllMain; No need to ever mix two mains together, the DllMain is the required one. error LNK2019: unresolved external symbol _D4core3sys7windows3dll18dll_process_attachFPvbZb referenced in function DllMain This is just betterC breaking the code.
Re: betterC DLL in Windows
You don't have access to druntime/Phobos stuff at runtime. SimpleDllMain is for initializing and uninitializing druntime. See: https://github.com/Project-Sidero/basic_memory/blob/main/source/sidero/base/dllmain.d You want to only use ldc atm. The defaults right now should most likely "just work" in dub for a single compile + link step (i.e. only a single static library in dll). If you do it manually, you'll want to add the flag ``--fvisibility=public`` to export everything.
betterC DLL in Windows
Hi, I'm new to D and trying my hands on a few simple things. Being able to build a Windows DLL with betterC enabled is of particular interest to me, as I'd need it for a project that I'd like to do in D. I'm trying to follow some examples, such as [this](https://wiki.dlang.org/Win32_DLLs_in_D) and [this](https://tekmoji.com/?post=Calling%20D%20(dlang)%20shared%20libs%20from%20Python%20on%20Windows), and they compile without `-betterC`, but fail with link errors when using the switch. example DLL, or see 2nd link for one without the mixin ```D //WindowsApp1.d module WindowsApp1; import core.sys.windows.windows; import core.sys.windows.dll; export extern (C) void main() { import core.stdc.stdio : printf; printf("Hello betterC\n"); } mixin SimpleDllMain; ``` then ``` dmd -m64 -shared -betterC WindowsApp1.d ``` yields error: ``` error LNK2019: unresolved external symbol _D4core3sys7windows3dll18dll_process_attachFPvbZb referenced in function DllMain error LNK2019: unresolved external symbol _D4core3sys7windows3dll18dll_process_detachFPvbZv referenced in function DllMain error LNK2019: unresolved external symbol _D4core3sys7windows3dll17dll_thread_attachFbbZb referenced in function DllMain error LNK2019: unresolved external symbol _D4core3sys7windows3dll17dll_thread_detachFbbZb referenced in function DllMain ``` I'm not a complete beginner to programming, so I'm guessing the linker is missing a library, but as I'm not familiar with D yet, and these are fairly basic examples that I expected to run without a hitch, I'm a bit confused as to what I should be doing. Shouldn't the system modules provide the link targets themselves? Should I add a parameter to include a windows system library? BtW, I've tried compiling from the command line and from Visual Studio using the visuald extension - I'm assuming the extension makes sure the environment variables are set correctly. When using dmd from the command line, I also tried invoking `dmd2vars64.bat` and `vcvars64.bat` before running dmd.exe to ensure the variables are set. In any case, the build process is successful without `betterC`, so I'm assuming the path/variables are set correctly.
Re: [Win32 API] MessageBox Example without MSVCR120.dll dependency
On Sunday, 25 December 2022 at 18:30:12 UTC, BoQsc wrote: This is a working Hello World example without dependency on Microsoft C Runtime Library, I couldn't find anything by searching around the forums or search engines, so I'm posting it here. Please provide improvements if you feel like something is missing or incorrect. My solution, 1068 bytes :) https://forum.dlang.org/post/trsunkhmxurvvsrsx...@forum.dlang.org
Re: [Win32 API] MessageBox Example without MSVCR120.dll dependency
to avoid special compile command just add one code line: pragma(lib, "user32.lib");
Re: [Win32 API] MessageBox Example without MSVCR120.dll dependency
On Sunday, 25 December 2022 at 18:30:12 UTC, BoQsc wrote: This is a working Hello World example without dependency on Microsoft C Runtime Library you might also consider using `-m32omf` switch to dmd which will make it bundle the old digital mars c lib. this is generally worse but since it is bundled it can be convenient.
[Win32 API] MessageBox Example without MSVCR120.dll dependency
This is a working Hello World example without dependency on Microsoft C Runtime Library, I couldn't find anything by searching around the forums or search engines, so I'm posting it here. Please provide improvements if you feel like something is missing or incorrect. **How to Compile:** `dmd "./MessageBox_HelloWorld.d" "user32.lib"` **Note:** This example can only be compiled with a 32 bit dmd compiler that exists in `.\dmd2\windows\bin\dmd.exe` **Observations:** * This example will generate a 208kb MessageBox_HelloWorld.exe binary * This example is independent of MSVCR120.dll * This example will open additional Command Prompt Window alongside the MessageBox_HelloWorld.exe **MessageBox_HelloWorld.d** ``` module MessageBox_HelloWorld; // A Win32 API Hello World MessageBox Example without MSVCR120.dll dependency // Tested on Windows 10, 2022.12.25 // DMD32 D Compiler v2.101.1-dirty import core.sys.windows.winuser : MessageBoxA, MB_OK; void main() { MessageBoxA(null, "Hello, World!", "My Win32 App", MB_OK); } ``` ![Screenshot](https://i.ibb.co/bvJ392k/Screenshot-1.png)
Re: How to link a msvcr120.dll in an inverse recursive way after a Windows .exe binary deployment
On Tuesday, 6 September 2022 at 04:59:49 UTC, Mike Parker wrote: On Tuesday, 6 September 2022 at 04:36:55 UTC, ShadoLight wrote: True. In that case just distribute the DLL (taken from the DMD bin folder) alongside the HelloWorld EXE so that both reside in the same folder on the target computer. The proper way to do this is to ship the correct version of the Visual C++ redistributable installer and run it as part of the application install process: https://docs.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170 Sure. But the OP seems to indicate that he doesn't have administrative privileges on the machines they wish to distribute and test his HelloWorld example. I don't know if you can run an installer without administrative privileges - at least not if you want to write to Program Files / Program Files (x86), modify the Registry, environment variables, etc. I'm not even sure if you can create a folder on Windows 10 without administrative rights without resorting to some tricks. I've never required that - and would think that the IT department (that handles installs and updates on their organization's computers) should have an admin account on all of them. My take was that he can simply copy the EXE and associated DLLs to an existing folder on the target machine if he just want to test it running on a non-developer machine. Making an installer is another mini-project by itself .. not sure if he wants to be burdened with such a step simply to resolve his DMD issue. But your redistributable installer link is indeed the proper way.
Re: How to link a msvcr120.dll in an inverse recursive way after a Windows .exe binary deployment
On Tuesday, 6 September 2022 at 04:36:55 UTC, ShadoLight wrote: True. In that case just distribute the DLL (taken from the DMD bin folder) alongside the HelloWorld EXE so that both reside in the same folder on the target computer. The proper way to do this is to ship the correct version of the Visual C++ redistributable installer and run it as part of the application install process: https://docs.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170
Re: How to link a msvcr120.dll in an inverse recursive way after a Windows .exe binary deployment
On Monday, 5 September 2022 at 07:02:53 UTC, BoQsc wrote: The problem is, D Language Compiler is not included along the Windows Operating System. No compiler is included natively with the Windows OS. Not even Microsoft's. Neither msvcr120.dll is included along the Windows Operating System. You have to download it. No other way. Or... you download the DMD installer which conveniently include it for you. How can you download it, if your .exe binary that has the functionality to download it, cannot even be started due to msvcr120.dll not existing on the operating system. I don't understand this. You need DMD to build your EXE. I suppose you have this since your question is specifically about DMD. If that is the case you have the DLL you need. Copy the DLL to C:\Windows\System32\ It required administrator privilegies and this is only a HelloWorld example of the D language deployed on computers, where the D language is yet to be installed. True. In that case just distribute the DLL (taken from the DMD bin folder) alongside the HelloWorld EXE so that both reside in the same folder on the target computer. If you don't have administrative priveleges you cannot modify the PATH on the target computer either, so this is the only way. That is anyway quite standard under Windows - if you search for msvcr*.dll on any Windows machine you'll find lots of copies co-located with the EXEs that use them (using the version that came with the specific version of Visual Studio they were using to build the EXE - for example msvcr90.dll). These DLLs are simply the Visual Studio C/C++ Runtime distributed with Visual Studio.
Re: How to link a msvcr120.dll in an inverse recursive way after a Windows .exe binary deployment
On Sunday, 4 September 2022 at 22:05:24 UTC, ShadoLight wrote: On Sunday, 4 September 2022 at 15:16:47 UTC, BoQsc wrote: **Folder structure** .\msvcr120.dll .\folder1\HelloWorld.exe .\folder2\HelloWorld.exe You don't need to do this. msvcr120.dll is already shipped with the DMD compiler at [DMD-install-folder]\windows\bin64\msvcr120.dll. (It is also in [DMD-install-folder]\windows\bin). You can access it directly from there. The problem is, D Language Compiler is not included along the Windows Operating System. Neither msvcr120.dll is included along the Windows Operating System. You have to download it. No other way. How can you download it, if your .exe binary that has the functionality to download it, cannot even be started due to msvcr120.dll not existing on the operating system. You can try to use pre-existing Command Line Utilities like bitsadmin (Windows 7), curl (Windows 10), but really how can you interact with them from within D Language Binary if it can't even launch. You can try to write a batch script for all that. I really do not want to write batch scripts for the rest of my life, that's why I'm here in the D Language Forum. Copy the DLL to C:\Windows\System32\ It required administrator privilegies and this is only a HelloWorld example of the D language deployed on computers, where the D language is yet to be installed.
Re: How to link a msvcr120.dll in an inverse recursive way after a Windows .exe binary deployment
On Sunday, 4 September 2022 at 15:16:47 UTC, BoQsc wrote: **Folder structure** .\msvcr120.dll .\folder1\HelloWorld.exe .\folder2\HelloWorld.exe You don't need to do this. msvcr120.dll is already shipped with the DMD compiler at [DMD-install-folder]\windows\bin64\msvcr120.dll. (It is also in [DMD-install-folder]\windows\bin). You can access it directly from there. When you run your EXE... the OS looks for the DLL in the same folder of the EXE- if it cannot find it it looks in the folders specified in your PATH. You can test if this is the case by executing 'where msvcr120.dll' at a DOS console command prompt. If the DLL is reachable in any folder in your PATH environment variable these specific path(s) will be displayed. In this case you don't need to do anything - the EXE should be able to run and load the DLL. The fact that you get this error indicate this is not the case. You can do 1 of the following 2 things: - add your DMD bin64 (or bin) path to the PATH environment variable. --or-- - Copy the DLL to C:\Windows\System32\ - that will for sure already be in your PATH so you don't need to modify your PATH environment variable.
Re: How to link a msvcr120.dll in an inverse recursive way after a Windows .exe binary deployment
I've been reading up fairly recently on RPATH for *nix which does what you want. Unfortunately as far as I've found there is no way to do this on Windows without an extra executable.
How to link a msvcr120.dll in an inverse recursive way after a Windows .exe binary deployment
![HelloWorld](https://i.imgur.com/5BjVIU9.png) **Folder structure** .\msvcr120.dll .\folder1\HelloWorld.exe .\folder2\HelloWorld.exe Basic binaries produced by DMD.exe compiler require Microsoft Compiler Runtime DLL As you might know that a basic D Language example `HelloWorld.exe` requires `msvcr120.dll` to work. Linking inverse recursively? **To not include** `msvcr120.dll` into every `.exe` executable's `.\folder\` **and to not marginally increase the overall size of the project**: I'd like to link every `.\folder\.exe` binary to the `.\msvcr120.dll` dynamic library. **Notice** Launching the `.exe` binary with external script to change the `path` variable is not a solution. I'd like the `.exe` binary to "know" and try to search for `.\msvcr120.dll` by itself after clicking it to launch.
Re: How to call a function from a dll created with d ?
On Thursday, 7 July 2022 at 17:29:42 UTC, cc wrote: Does importing dimedll into app.d properly NOT link in the functions that are exported to the DLL? When I tried something similar with dmd, I had to create a .di file containing just stubs, otherwise it looked like it was ignoring the DLL and compiling in an additional copy of each fuction. IMHO this is the expected behaviour since the compiler comes before the linker and `pragma(lib)` is a linker directive, so if dimedll.di is not present it looks for dimedll.d instead and just compiles the code. The link to DLL is only present in the actual lib-file and only used by the linker. The pitfall with DMD is that the automatic generated di-file is not usable as it contains a mixin that is meant for the DLL but not the application that links it, resulting in _ModuleInfoZ error while trying.
Re: How to call a function from a dll created with d ?
On Saturday, 2 July 2022 at 20:43:41 UTC, Vinod KC wrote: On Saturday, 2 July 2022 at 14:32:11 UTC, apz28 wrote: dmd -of=dimedll.dll dimedll.d dimedll.def dmd dime.d dimedll.di Thanks for the reply. Well, I am sorry to say that your suggestions resulted in failure. First of all, when I used this command -- ` dmd -of=dimedll.dll dimedll.d dimedll.def` I got this error message- `Error: unrecognized file extension dll`. So I avoided the `-of=dimedll.dll` part. Then I compiled it with this command - `dmd -H dimedll.d dimedll.def` And I got some warnings. Here are they. ```d dimedll.def(2) : warning LNK4017: EXETYPE statement not supported for the target platform; ignored dimedll.def(3) : warning LNK4017: SUBSYSTEM statement not supported for the target platform; ignored dimedll.def(4) : warning LNK4017: CODE statement not supported for the target platform; ignored dimedll.def(4) : warning LNK4017: DATA statement not supported for the target platform; ignored Creating library dimedll.lib and object dimedll.exp ``` I know all of them are from my `def` file. Anyways, I stepped forward and tried to run the main file with this dll & lib. So I ran this command. - `dmd dime.d dimedll.di`. But I got this error message. ```d dime.obj : error LNK2001: unresolved external symbol __D7dimedll12__ModuleInfoZ dime.exe : fatal error LNK1120: 1 unresolved externals Error: linker exited with status 1120 ``` First issue - you're using dmd on windows. Dmd gives me errors about the ModuleInfo, while LDC doesn't. [This is the LDC download link.](https://github.com/ldc-developers/ldc/releases/download/v1.29.0/ldc2-1.29.0-windows-multilib.exe) Next, change dimedll.d to the following: ```d module dimedll; export void testFunc() { import std.stdio; writeln("Lets build our own ime."); } ``` and dime.d to the following: ```d import dimedll; //In case you ever write more functions for dimedll.d; pragma(lib, "dimedll.lib"); void main() { testFunc(); } ``` Then run ```ldc2 -shared dimedll.d``` and right after that ```ldc2 dime.d```. If I didn't make a mistake in writing this (I tested it on my own system), it should output a working program that prints the expected output when ran.
Re: How to call a function from a dll created with d ?
On Sunday, 3 July 2022 at 09:43:20 UTC, frame wrote: app.d: ```d module app; import dimedll; import std.stdio; import std.stdio : log = writeln; pragma(lib, "dimedll.lib"); void main() { log("Lets build our own ime"); testFunc(); } ``` You should be able to change contents in the DLL and run the executable wihtout re-compiling (the library file should be round ~2kB). PS: ddemangle just waits for your input. You copy in the mangled symbol like `__D7dimedll12__ModuleInfoZ` and press enter ;-) Does importing dimedll into app.d properly NOT link in the functions that are exported to the DLL? When I tried something similar with dmd, I had to create a .di file containing just stubs, otherwise it looked like it was ignoring the DLL and compiling in an additional copy of each fuction.
Re: How to call a function from a dll created with d ?
On Sunday, 3 July 2022 at 16:48:52 UTC, frame wrote: Only the -H switch or manual linker command generates a valid link to the DLL with DMD but then it's missing all the other library contents (also it needs `SimpleDllMain` or bails out linking errors to `_calloc` and Windows symbols) :\ `dmd -shared` / `dmd -H -shared` seems to work too (library contains link to DLL). Don't know why I had in mind that it would fail - maybe it did in the past. However both DMD and LDC produces questionable header files for this task.
Re: How to call a function from a dll created with d ?
On Sunday, 3 July 2022 at 12:54:45 UTC, kinke wrote: On Sunday, 3 July 2022 at 08:15:38 UTC, frame wrote: Are you sure? 100%, just try yourself. Why would the symbol be defined in the executable? `dimedll.d` isn't compiled into the executable. The code is using Phobos std.stdio.writeln templates, so the ~20 KB for both exe and DLL are to be expected and IMO absolutely acceptable. DMD's DLL support is waaay behind LDC's, especially once stuff gets more interesting than trivial examples. Yeah, I tried LDC and there are differences: The library file generated by LDC contains the link to the DLL. The library file generated by DMD is missing that link. So linking the DMD library would embed the symbol from the library - that was my confusion with your example. Only the -H switch or manual linker command generates a valid link to the DLL with DMD but then it's missing all the other library contents (also it needs `SimpleDllMain` or bails out linking errors to `_calloc` and Windows symbols) :\ Also the -H switch doesn't work correctly. Without supplying -L/DLL flag too, I get link error: ``` 1561: entry point must be defined ```
Re: How to call a function from a dll created with d ?
On Sunday, 3 July 2022 at 08:15:38 UTC, frame wrote: Are you sure? 100%, just try yourself. You import `testFunc` as normal import, the compiler ignores `pragma(lib)` - that's only for the linker which will ignore it too since the symbol is already in your executable. Why would the symbol be defined in the executable? `dimedll.d` isn't compiled into the executable. A static linked function should generate a very small lib-file and yours look too big to me. The code is using Phobos std.stdio.writeln templates, so the ~20 KB for both exe and DLL are to be expected and IMO absolutely acceptable. I don't know about LDC but with DMD I struggle with static linked DLLs because the library generated does not link to the DLL. To get right results, I need to pass the linker flag -`-L=/IMPLIB` (or `-L=/DLL` for 64bit) to generate a lib-file that is really linked to the DLL later. DMD's DLL support is waaay behind LDC's, especially once stuff gets more interesting than trivial examples.
Re: How to call a function from a dll created with d ?
On Saturday, 2 July 2022 at 20:43:41 UTC, Vinod KC wrote: But I got this error message. dime.obj : error LNK2001: unresolved external symbol __D7dimedll12__ModuleInfoZ dime.exe : fatal error LNK1120: 1 unresolved externals Error: linker exited with status 1120 I tried the -H switch. You can't rely on that. I comment the lines that shouldn't be there - then it should work: dimedll.di ```d // D import file generated from 'dimedll.d' module dimedll; // import core.sys.windows.dll; // import std.stdio; // mixin SimpleDllMain!(); export void testFunc(); ``` dimedll.d: ```d module dimedll; import core.sys.windows.dll; import std.stdio; mixin SimpleDllMain; export void testFunc() { writeln("This is from dll"); } ``` app.d: ```d module app; import dimedll; import std.stdio; import std.stdio : log = writeln; pragma(lib, "dimedll.lib"); void main() { log("Lets build our own ime"); testFunc(); } ``` You should be able to change contents in the DLL and run the executable wihtout re-compiling (the library file should be round ~2kB). PS: ddemangle just waits for your input. You copy in the mangled symbol like `__D7dimedll12__ModuleInfoZ` and press enter ;-)
Re: How to call a function from a dll created with d ?
On Saturday, 2 July 2022 at 14:06:03 UTC, kinke wrote: With LDC, this is sufficient for this trivial example: ```d module dimedll; export void testFunc() { // export only needed when compiling with `-fvisibility=hidden` import std.stdio; writeln("This is from dll"); } ``` `ldc2 -shared dimedll.d` generates import lib + DLL. ```d import dimedll : testFunc; pragma(lib, "dimedll"); void main() { import std.stdio; writeln("Lets build our own ime"); testFunc(); } ``` `ldc2 -link-defaultlib-shared dime.d` generates the .exe and makes it share the druntime/Phobos DLLs with `dimedll.dll`. (More complex cases might need `-dllimport=all`). ``` C:\temp\dllTest>dime Lets build our own ime This is from dll C:\temp\dllTest>dir … 07/02/2022 03:54 PM 155 dime.d 07/02/2022 03:57 PM18,432 dime.exe 07/02/2022 03:57 PM19,679 dime.obj 07/02/2022 03:56 PM 162 dimedll.d 07/02/2022 03:57 PM20,480 dimedll.dll 07/02/2022 03:57 PM 7,534 dimedll.exp 07/02/2022 03:56 PM13,036 dimedll.lib 07/02/2022 03:57 PM21,233 dimedll.obj ``` On Posix, the only difference is that one would have to link `libdimedll.{so,dylib}` explicitly via `-L-ldimedll` instead of the `pragma(lib)`. This is from dll Are you sure? You import `testFunc` as normal import, the compiler ignores `pragma(lib)` - that's only for the linker which will ignore it too since the symbol is already in your executable. If you can run your exectuable without dimedll.dll present, then the function is **not** statically linked in. A static linked function should generate a very small lib-file and yours look too big to me. I don't know about LDC but with DMD I struggle with static linked DLLs because the library generated does not link to the DLL. To get right results, I need to pass the linker flag -`-L=/IMPLIB` (or `-L=/DLL` for 64bit) to generate a lib-file that is really linked to the DLL later.
Re: How to call a function from a dll created with d ?
On Saturday, 2 July 2022 at 21:36:50 UTC, mw wrote: Actually, can you create a github repo, I'm sure people will send you a working PR. Yes I can. I will inform here once I did it.
Re: How to call a function from a dll created with d ?
On Saturday, 2 July 2022 at 20:43:41 UTC, Vinod KC wrote: On Saturday, 2 July 2022 at 14:32:11 UTC, apz28 wrote: dmd -of=dimedll.dll dimedll.d dimedll.def dmd dime.d dimedll.di Thanks for the reply. Well, I am sorry to say that your suggestions resulted in failure. First of all, when I used this command -- ` dmd -of=dimedll.dll dimedll.d dimedll.def` I got this error message- `Error: unrecognized file extension dll`. Actually, can you create a github repo, I'm sure people will send you a working PR.
Re: How to call a function from a dll created with d ?
On Saturday, 2 July 2022 at 14:32:11 UTC, apz28 wrote: dmd -of=dimedll.dll dimedll.d dimedll.def dmd dime.d dimedll.di Thanks for the reply. Well, I am sorry to say that your suggestions resulted in failure. First of all, when I used this command -- ` dmd -of=dimedll.dll dimedll.d dimedll.def` I got this error message- `Error: unrecognized file extension dll`. So I avoided the `-of=dimedll.dll` part. Then I compiled it with this command - `dmd -H dimedll.d dimedll.def` And I got some warnings. Here are they. ```d dimedll.def(2) : warning LNK4017: EXETYPE statement not supported for the target platform; ignored dimedll.def(3) : warning LNK4017: SUBSYSTEM statement not supported for the target platform; ignored dimedll.def(4) : warning LNK4017: CODE statement not supported for the target platform; ignored dimedll.def(4) : warning LNK4017: DATA statement not supported for the target platform; ignored Creating library dimedll.lib and object dimedll.exp ``` I know all of them are from my `def` file. Anyways, I stepped forward and tried to run the main file with this dll & lib. So I ran this command. - `dmd dime.d dimedll.di`. But I got this error message. ```d dime.obj : error LNK2001: unresolved external symbol __D7dimedll12__ModuleInfoZ dime.exe : fatal error LNK1120: 1 unresolved externals Error: linker exited with status 1120 ```
Re: How to call a function from a dll created with d ?
Below is working on Windows --file dimedll.d: module dimedll; import core.sys.windows.windows; import core.sys.windows.dll; import std.stdio; mixin SimpleDllMain; export void testFunc() { writeln("This is from dll"); } --file dime.d: import core.sys.windows.windows; import std.stdio; import dimedll; pragma(lib, "dimedll.lib"); void main() { writeln("Lets call testFunc()"); testFunc(); } --file dimedll.di: module dimedll; extern void testFunc(); --file dimedll.def LIBRARY "dimedll.dll" EXETYPE NT SUBSYSTEM WINDOWS CODE SHARED EXECUTE DATA WRITE -- command lines in sequence: -- there should be files as first dmd: dimedll.exp, dimedll.lib, dimedll.obj dmd -of=dimedll.dll dimedll.d dimedll.def dmd dime.d dimedll.di
Re: How to call a function from a dll created with d ?
With LDC, this is sufficient for this trivial example: ```d module dimedll; export void testFunc() { // export only needed when compiling with `-fvisibility=hidden` import std.stdio; writeln("This is from dll"); } ``` `ldc2 -shared dimedll.d` generates import lib + DLL. ```d import dimedll : testFunc; pragma(lib, "dimedll"); void main() { import std.stdio; writeln("Lets build our own ime"); testFunc(); } ``` `ldc2 -link-defaultlib-shared dime.d` generates the .exe and makes it share the druntime/Phobos DLLs with `dimedll.dll`. (More complex cases might need `-dllimport=all`). ``` C:\temp\dllTest>dime Lets build our own ime This is from dll C:\temp\dllTest>dir … 07/02/2022 03:54 PM 155 dime.d 07/02/2022 03:57 PM18,432 dime.exe 07/02/2022 03:57 PM19,679 dime.obj 07/02/2022 03:56 PM 162 dimedll.d 07/02/2022 03:57 PM20,480 dimedll.dll 07/02/2022 03:57 PM 7,534 dimedll.exp 07/02/2022 03:56 PM13,036 dimedll.lib 07/02/2022 03:57 PM21,233 dimedll.obj ``` On Posix, the only difference is that one would have to link `libdimedll.{so,dylib}` explicitly via `-L-ldimedll` instead of the `pragma(lib)`.
Re: How to call a function from a dll created with d ?
On Saturday, 2 July 2022 at 01:05:25 UTC, Ali Çehreli wrote: 3) The users of this dll should import that .di file (declaring the functions themselves won't work): Ali Hi, Thanks for the reply. I have tried your suggestion. First, I compiled my dll's source code with `-H` switch as you said. Then I got the header file with this content. ```d // D import file generated from dimedll.d module dimedll; import core.sys.windows.windows; import core.sys.windows.dll; import std.stdio; mixin SimpleDllMain!(); export void testFunc(); ``` So far so good. Then I change my `dime.d` source file like this. ```d import dimedll; void main() { log("Lets build our own ime"); testFunc(); } ``` Unfortunately, I got this error message. dime.obj : error LNK2019: unresolved external symbol __imp___D7dimedll8testFuncFZv referenced in function __Dmain dime.obj : error LNK2001: unresolved external symbol __D7dimedll12__ModuleInfoZ dime.exe : fatal error LNK1120: 2 unresolved externals Error: linker exited with status 1120 Then I have tested with `dimedll.testFunc()` instead of `testFunc()` at the calling site. Then also I got an error message like this. dime.obj : error LNK2019: unresolved external symbol __imp___D7dimedll8testFuncFZv referenced in function __Dmain dime.obj : error LNK2001: unresolved external symbol __D7dimedll12__ModuleInfoZ dime.exe : fatal error LNK1120: 2 unresolved externals Error: linker exited with status 1120 I want to test this with ddemangle.exe, but there is no proper documentation for that tool. So I don't know how to use that tool. So Actually I am stuck.
Re: How to call a function from a dll created with d ?
On 7/1/22 12:11, Vinod KC wrote: The following function is dimedll.testFunc: > ```d > module dimedll; // ... > export void testFunc() { > writeln("This is from dll"); > } > ``` We suspect the name of the file that defines main() is dime.d. > extern void testFunc(); That symbol belongs to this module, which is implied to be 'module dime'. > testFunc(); That's a call to dime.testFunc, which does not exist. With the provided information alone, the following is what I would do: 1) This dll must have a .di file, which should contain the following: // dimedll.di void testFunc(); (.di files can be generated by dmd with its -H command line switch.) 2) Provide dimedll.di as your library's interface file (a la "header file"). 3) The users of this dll should import that .di file (declaring the functions themselves won't work): import dimedll; void main() { // ... } Ali
Re: How to call a function from a dll created with d ?
On Saturday, 2 July 2022 at 00:23:20 UTC, Ruby The Roobster wrote: The solution is to remove the extern declaration. That does it for me, and it prints the expected output. No need for a .def file, unless you are using optlink as your linker (which, as a matter of principle, you should use lld or ld instead.) Thank you for the reply. Let me try that.
Re: How to call a function from a dll created with d ?
The solution is to remove the extern declaration. That does it for me, and it prints the expected output. No need for a .def file, unless you are using optlink as your linker (which, as a matter of principle, you should use lld or ld instead.)
Re: How to call a function from a dll created with d ?
On Friday, 1 July 2022 at 22:38:17 UTC, Adam D Ruppe wrote: On Friday, 1 July 2022 at 22:32:24 UTC, Vinod K Chandran wrote: So using a `def` file is a must I think. no it is not. you just need to mark things export and make sure names match (including module name) Thanks for the reply. These are my questions. 1. `mixin` statement in dll file - Do I need to export it ? 2. There is only one function and that is marked with `export`. 3. Name of the module which I wrote the dll code is `dimedll`. So my dll file's name is `dimedll.dll`. And my lib file's name is `dimedll.lib`. No change in names. 4. Name of my exported function is `testFunc`. And the same name is used in `extern` keyword and the calling site. So where do I check again ?
Re: How to call a function from a dll created with d ?
On Friday, 1 July 2022 at 22:32:24 UTC, Vinod K Chandran wrote: So using a `def` file is a must I think. no it is not. you just need to mark things export and make sure names match (including module name)
Re: How to call a function from a dll created with d ?
On Friday, 1 July 2022 at 22:22:42 UTC, mw wrote: Try follow instructions here: https://wiki.dlang.org/Win32_DLLs_in_D Thanks. So using a `def` file is a must I think. At first, I thought I can skip that.
Re: How to call a function from a dll created with d ?
On Friday, 1 July 2022 at 21:15:50 UTC, Vinod K Chandran wrote: On Friday, 1 July 2022 at 21:02:20 UTC, mw wrote: I think the problem is the linker looking for dime.testFunc, while your lib function is dimedll.testFunc Thanks for the reply. What about this `mixin SimpleDllMain;` I suspect this. Try follow instructions here: https://wiki.dlang.org/Win32_DLLs_in_D
Re: How to call a function from a dll created with d ?
On Friday, 1 July 2022 at 21:02:20 UTC, mw wrote: I think the problem is the linker looking for dime.testFunc, while your lib function is dimedll.testFunc Thanks for the reply. What about this `mixin SimpleDllMain;` I suspect this.
Re: How to call a function from a dll created with d ?
On Friday, 1 July 2022 at 19:11:16 UTC, Vinod KC wrote: Hi all, I have created a dll file with this code. ```d module dimedll; export void testFunc() { writeln("This is from dll"); } ``` void main() { log("Lets build our own ime"); testFunc(); } ``` ``` dime.obj : error LNK2019: unresolved external symbol __D4dime8testFuncFZv referenced in I think the problem is the linker looking for dime.testFunc, while your lib function is dimedll.testFunc
Re: How to call a function from a dll created with d ?
On Friday, 1 July 2022 at 20:08:45 UTC, ryuukk_ wrote: I think it is `extern(D) void testFunc();`? Thanks for the reply. But the result is same linker error.
Re: How to call a function from a dll created with d ?
I think it is `extern(D) void testFunc();`?
How to call a function from a dll created with d ?
Hi all, I have created a dll file with this code. ```d module dimedll; import core.sys.windows.windows; import core.sys.windows.dll; // I don't what is this for. import std.stdio; mixin SimpleDllMain; export void testFunc() { writeln("This is from dll"); } ``` So now I have a dll fie named `dimedll.dll` and a lib file named `dimedll.lib`. Now, I have created a d source file called `dime.d` and wrote this code. ```d import std.stdio; import core.sys.windows.windows; import std.stdio : log = writeln; pragma(lib, "dimedll.lib"); extern void testFunc(); void main() { log("Lets build our own ime"); testFunc(); } ``` Everything seems to be okay. So I called dmd with this command. `dmd -i -run dime.d` But I got this error message. ``` dime.obj : error LNK2019: unresolved external symbol __D4dime8testFuncFZv referenced in function __Dmain dime.exe : fatal error LNK1120: 1 unresolved externals Error: linker exited with status 1120``` How to fix this ?
Re: Creating DLL
On Thursday, 16 June 2022 at 16:19:22 UTC, Ali Çehreli wrote: On 6/16/22 09:07, Sergeant wrote: This answer may be relevant: https://forum.dlang.org/post/t8diks$2l79$1...@digitalmars.com Ali, thank you, I'll take a look.
Re: Creating DLL
Adam, thank you again! Adding Initialize()/Terminate() to code and calling from my application as you suggested didn't help, unfortunately. Maybe the problem is in the scripting language I'm using (AHK) which is not designed to handle situations like these. In any case, appreciate your help!
Re: Creating DLL
On Thursday, 16 June 2022 at 16:37:34 UTC, Ali Çehreli wrote: Agreed but that excludes using the D runtime in 'static this' (and shared) blocks, right? It is runtime.initialize that calls those `static this` blocks. If my explicit call to Initialize is in a 'shared static this' This is backward - the explicit call to Initalize is in the exe. It'd look like: // this code is in the exe! pretend it is C++ or whatever HANDLE lib = LoadLibrary("my_d_lib.dll"); if(lib !is null) { auto fn = cast(typeof(init_func)) GetProcAddress("Initialize"); if(fn !is null) { fn(); // this now calls runtime.initialize which calls the static this blocks etc // you're now good to call any D functions } }
Re: Creating DLL
On 6/16/22 09:32, Adam D Ruppe wrote: > This is why an explicit initialization call is the preferred method - > there, the time it is called is well-defined by the user after initial > loading is complete. Agreed but that excludes using the D runtime in 'static this' (and shared) blocks, right? If my explicit call to Initialize is in a 'shared static this', then I can have only one such block, right? Ali
Re: Creating DLL
On Thursday, 16 June 2022 at 16:19:22 UTC, Ali Çehreli wrote: pragma (crt_constructor) You have to be pretty careful about this since it might not run in the order you expect. If there's two things in the program with a equal-priority crt constructor, they are run in arbitrary order. In a shared lib, there's also the possibility that loader locks are in place, and if it runs rt_init specifically, that can run D module constructors... which might load other libraries. Similar concerns apply to doing rt_init in DllMain. This is why an explicit initialization call is the preferred method - there, the time it is called is well-defined by the user after initial loading is complete.
Re: Creating DLL
On 6/16/22 09:07, Sergeant wrote: > May I ask one more question: why a code like this would work in > D-application but not in D-DLL? D programs generated by D compilers automatically initialize the D runtime. You can do the same with rt_init: pragma (crt_constructor) extern(C) int initialize() { // Can have any name return rt_init(); } And to deinitialize; pragma (crt_destructor) extern(C) int terminate() { // Can have any name return rt_term(); } Although, I haven't tested it with a DLL but with .so libraries on Linux... :/ This answer may be relevant: https://forum.dlang.org/post/t8diks$2l79$1...@digitalmars.com Ali
Re: Creating DLL
On Thursday, 16 June 2022 at 16:07:41 UTC, Sergeant wrote: May I ask one more question: why a code like this would work in D-application but not in D-DLL? (also I notice some other D functions don't work in DLL): Probably because the runtime not initialized properly. Export an Initialize() and Terminate() functions and call them from your application loading the dll. Inside those functions: export extern(C) void Initialize() { import core.runtime; Runtime.initialize(); } export extern(C) void Terminate() { import core.runtime; Runtime.terminate(); } If you call those the other functions should start working. (this is a fairly common thing libraries need to do, but it might be tricky if you are loading the dll into an uncooperative application, there's other hacks for that, but having your functions like this and the app calling them are the right way to do it)
Re: Creating DLL
Adam thank you, it works now! May I ask one more question: why a code like this would work in D-application but not in D-DLL? (also I notice some other D functions don't work in DLL): import std.string; export extern(C) string my(string input) { string output = ""; auto lines = input.lineSplitter(); foreach (line; lines){ output ~= line; } return output }
Re: Creating DLL
On Thursday, 16 June 2022 at 13:57:48 UTC, Sergeant wrote: export int my(int a, int b) the name here is going to be mangled, so like "_D5mydll2myiiZi" or something like that. You might want to add `extern(C)` to it so it keeps the simple name "my", that might help.
Creating DLL
Hi, I wonder if anyone knowledgeable can point me in the right direction here. I created DLL in Visual D, but when I try to use it by my application (AHK script), DLL itself is loaded ok, but error is set to "specified function could not be found inside the DLL". (Same DLL that I made in C++ works, but this doesn't somehow) Sample code looks like this: module my_dll; import core.sys.windows.windows; import core.sys.windows.dll; export int my(int a, int b) { // ... my code ... // return output; } mixin SimpleDllMain; I set "-shared" switch in VS. Is there anything I'm missing here? Thanks!
Re: D's dll and classes
On Sunday, 19 September 2021 at 12:00:22 UTC, Hipreme wrote: 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 tried writing only .di file for it, but then it would only get undefined symbol. What I expected is: You may need to use the [`export` attribute][1] to make symbols in the DLL visible to the main program. [1]: https://dlang.org/spec/attribute.html#visibility_attributes
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
Re: Error load: QtE5Widgets64.dll
On Tuesday, 31 August 2021 at 17:55:33 UTC, Kagamin wrote: Maybe you're trying to load a 32-bit library into a 64-bit process. Hmm, it's precompiled and the 64bit version should be a wrapper but I guess that it just doesn't work yet or needs a 64bit runtime as well. No idea where to get the runtime alone without downloading the whole QT framework... Indeed, the 32bit build works.
Re: Error load: QtE5Widgets64.dll
Maybe you're trying to load a 32-bit library into a 64-bit process.
Error load: QtE5Widgets64.dll
I'm Following the instruction by evilrat, https://forum.dlang.org/post/xljvxkqimdvvbvujc...@forum.dlang.org but apparently I'm to stupid to run the example. The application quits with `Error load: QtE5Widgets64.dll` which is located next to the EXE-file (also Qt5Core.dll, Qt5Gui.dll and Qt5Widgets.dll). The error is traced back to `Runtime.loadLibrary()` in `GetHlib()` in qte5.d but that's it. Not sure what Windows does at loading the Qt5Core.dll (it looks for multiple paths where the DLL is also present but it also locks the Qt5Core.dll in the application directory - according Process Monitor) but it seems that's the last DLL which is loaded before the thread is exited. Any hints are appreciated.
Re: OutOfMemoryError in D DLL appending to module-level array
On Sunday, 2 May 2021 at 02:42:46 UTC, Adam D. Ruppe wrote: On Sunday, 2 May 2021 at 02:34:41 UTC, cc wrote: which seems to fix it, but I'm not entirely sure what's going on, if this is expected behavior, if that's the correct way to handle it, and so on. Oh I've been working on this the last couple weeks and having a hard time reproducing outside the work application. In the work app, the GC wasn't scanning the dll's TLS variables and freeing them prematurely. In a sample test program, I used a thing kinda like yours, if a dll creates a thread and calls back into the exe you get a separate problem of partially initialize data. D dlls on Windows work in simple cases right now but break down in more advanced cases. The good news is there's major fixes coming soon - my druntime hack might be coming, gdc is getting full dll support very soon from mingw, there's a good chance ldc is going to in a release or two as well outside mingw. But the bad news is none of that is actually out right now, so dll + tls variables (which includes the top-level things on modules) are potentially buggy among other things like duplicated symbols. You might find some improvement making your variable __gshared there. But if you can do any reduced test case I'd really appreciate it. More tests that we can do in public is better! Cool, thanks for the update. Setting it as __gshared does seem to work. I put together some test cases here: https://gitlab.com/-/snippets/2114152 It's got the DLL written in D, and test programs for loading it in D, C#, and C++. I haven't done much .NET interop stuff but it seems to work. I'd welcome any recommendations on how to improve the interfaces if there are any, I made a little mixin to create C wrappers for the member functions since that seems to be the suggested solution for calling class methods.
Re: OutOfMemoryError in D DLL appending to module-level array
On Sunday, 2 May 2021 at 02:34:41 UTC, cc wrote: which seems to fix it, but I'm not entirely sure what's going on, if this is expected behavior, if that's the correct way to handle it, and so on. Oh I've been working on this the last couple weeks and having a hard time reproducing outside the work application. In the work app, the GC wasn't scanning the dll's TLS variables and freeing them prematurely. In a sample test program, I used a thing kinda like yours, if a dll creates a thread and calls back into the exe you get a separate problem of partially initialize data. D dlls on Windows work in simple cases right now but break down in more advanced cases. The good news is there's major fixes coming soon - my druntime hack might be coming, gdc is getting full dll support very soon from mingw, there's a good chance ldc is going to in a release or two as well outside mingw. But the bad news is none of that is actually out right now, so dll + tls variables (which includes the top-level things on modules) are potentially buggy among other things like duplicated symbols. You might find some improvement making your variable __gshared there. But if you can do any reduced test case I'd really appreciate it. More tests that we can do in public is better!