Skip to content

dl: remove workaround; cgen: add DllMain()#23961

Merged
spytheman merged 3 commits into
vlang:masterfrom
kbkpbot:fix-dllmain-under-windows
Mar 17, 2025
Merged

dl: remove workaround; cgen: add DllMain()#23961
spytheman merged 3 commits into
vlang:masterfrom
kbkpbot:fix-dllmain-under-windows

Conversation

@kbkpbot

@kbkpbot kbkpbot commented Mar 17, 2025

Copy link
Copy Markdown
Contributor

Fix issue #8313

When create .dll under windows, create a default DllMain() for it, which will call _vinit(0, (voidptr)0); and _vcleanup();.
Then we can remove the workaround in dl.open() and dl.close()

This is helpful when try to create dll can be called by non-v APPs.

@huly-for-github

Copy link
Copy Markdown

Connected to Huly®: V_0.6-22356

@spytheman spytheman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work.

@spytheman spytheman merged commit bd2ec67 into vlang:master Mar 17, 2025
@Ekopalypse

Copy link
Copy Markdown
Contributor

I can't understand how this is supposed to work in practice? How is the DLL informed that it has been loaded? In other words, when can the internal initialization take place?
Also, such a change is significant, why wasn't the current workaround announced as deprecated to detect any issues?
Yes, I know it wasn't V functionality - it was a workaround, but it worked ...

@JalonSolov

Copy link
Copy Markdown
Collaborator

From the Windows docs:

An optional entry point into a dynamic-link library (DLL). When the system starts or terminates a process or thread, it calls the entry-point function for each loaded DLL using the first thread of the process. The system also calls the entry-point function for a DLL when it is loaded or unloaded using the LoadLibrary and FreeLibrary functions.

For a DLL created by V, this function is always needed, so that _vinit() is called - this is the routine that initializes V's consts, etc.

Since this was not created by default in the past, people who ran into problems had to create their own DllMain() that called _vinit(), or use some sort of other hacky workaround.

If there was a "standard" workaround, then I agree, it should've been marked deprecated. I don't recall there being such a standard, but I don't do much with Windows (except complain about it).

@Ekopalypse

Copy link
Copy Markdown
Contributor

I know that, but the thing is that this PR killed all dlls that need to do an internal initialization, because with this PR the "V-internal" DllMain is called and thus the author of a dll can no longer tell when this happens.
I know I can work around that too, but then it's a different, and this time really hacky way to get it working again.
I already pointed out in the issue that this, a way to define how the dll's own code can be initialized, needs to be considered.

If there was a "standard" workaround ...

I would argue that the previous way was the standard workaround

@JalonSolov

Copy link
Copy Markdown
Collaborator

I think what should've been done was to make this auto DllMain() optional, only to be generated if there was no existing DllMain(). That way, if you wanted to do your own initialization, you would write your own DllMain().

This change is necessary if there is no DllMain() already, otherwise, DLLs created by V just silently don't work as expected. Of course, if you provide your own DllMain() and don't call _vinit(), you'll still get the same problem, but at least it could then be documented, and your own fault if you didn't read the docs.

One could argue that doing initialization any other way than with a DllMain() goes against the Windows specs, so is definitely not standard.

@Ekopalypse

Copy link
Copy Markdown
Contributor

I think what should've been ... optional ...

This would have been a possibility, yes.

This change is necessary

I would not say that this change is necessary, but yes, a change is necessary.
A change to the documentation would also have done the trick too.

One could argue that doing initialization any other way than with a DllMain() goes against the Windows specs, so is definitely not standard.

I don't know what is being referred to here. To my comment that the previous way was the quasi-standard? If so, then you have overlooked the fact that the previous way ultimately did exactly the same thing as this PR.
If you mean that V absolutely has to define a DllMain function to meet the Windows standard, then no, the Windows documentation explicitly says that the name DllMain is just a placeholder and therefore not mandatory. From the V point of view, you could define a separate entry point where vinit is run, just like for executable programs. Furthermore, a dll-specific function should definitely be called, which allows a dll author to perform dll-specific initialization. In other words, the V-own entry point should call a dll-specific function or functions with the same parameters.

@kbkpbot kbkpbot deleted the fix-dllmain-under-windows branch June 4, 2025 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants