Jump to page: 1 2 3
Thread overview
betterC DLL in Windows
Feb 04, 2023
Tamas
Feb 04, 2023
Tamas
Feb 04, 2023
bachmeier
Feb 05, 2023
Tamas
Feb 04, 2023
Adam D Ruppe
Feb 04, 2023
Tamas
Feb 04, 2023
Adam D Ruppe
Feb 04, 2023
Tamas
Feb 04, 2023
bachmeier
Feb 04, 2023
Adam D Ruppe
Feb 05, 2023
Adam D Ruppe
Feb 05, 2023
Tamas
Feb 06, 2023
Tamas
Feb 05, 2023
Tamas
Feb 06, 2023
bachmeier
Feb 06, 2023
H. S. Teoh
Feb 06, 2023
Tamas
Feb 04, 2023
ryuukk_
February 04, 2023

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 and this, 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

//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.

February 05, 2023
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.
February 04, 2023
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.
February 04, 2023
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.
February 04, 2023
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).
February 04, 2023

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:

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?

February 05, 2023
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 :)
February 04, 2023

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.

February 04, 2023

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.

February 04, 2023

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.

« First   ‹ Prev
1 2 3