extern(Windows, "user32.dll")

Benjamin Thaut via Digitalmars-d digitalmars-d at puremagic.com
Sun Feb 1 06:04:29 PST 2015


Am 01.02.2015 um 14:27 schrieb Vladimir Panteleev:
> On Sunday, 1 February 2015 at 12:09:56 UTC, Benjamin Thaut wrote:
>> http://wiki.dlang.org/DIP45
>
> OK, so I understand it's mostly about D DLLs.

Yes of course. Because they are still not supported.

>
> This bit though:
>
> "In an import library the original symbol is redifined as trampoline
> that simply dereferences the _imp_ pointer to the DLL function. Thus
> calling an exported function will be compatible with both import
> libraries and static libraries, in the later case without indirection."
>
> Is this different from how things are now?

No its not. I'm sticking with the additional indirection. But linking 
against a Dll directly would still be possbile. The linker has to 
generate the additional indirection anyway, no matter if a import 
library was used or not. This must be done because otherwise the code 
generated by the compiler, which assumes a additional indirection, would 
no longer be working (in case of data symbols only, function symbols 
would work without the indirection).

>
> Also, how does this conflict with my proposal?

It does not. The only conflict would be if we would ban import libraries 
completely, which I misunderstood.

> If the compiler knows the
> function to be in a DLL, it can elide generating a trampoline at all,
> and reference the __imp__ symbol directly.

Yes it could.

> That's a good point. It would be possible to define my proposal so that
> it would be easy to switch between the two with a -version switch. On
> one hand, you trade one compiler switch (static.lib or import.lib) for
> another (-version=static). On the other hand, for the DLL case, you skip
> the headache of import libraries.

Your proposal could also be translated to:

pragma(lib, "kernel32.dll");
extern(dll) DWORD GetVersion();

You just want a way to tell the compiler that that function is definitly 
located in a dll. The additional benefit of the above example would be, 
that you don't have to repeat which library the symbol is in for each 
symbol. The problem I see here is that walter didn't want to have a 
seperation between export and import. So he designed export to mean 
both. So I don't know how happy he will be if you want to add in a 
dllimport equivalent keyword. You could do however:


pragma(lib, "wininet.dll");
export extern(Windows) HINTERNET InternetOpen(
   LPCTSTR lpszAgent,
   DWORD dwAccessType,
   LPCTSTR lpszProxyName,
   LPCTSTR lpszProxyBypass,
   DWORD dwFlags
);

The fun thing is, this would work with the current dmd. If export is 
applied to a function declaration, it means "dllimport". That means 
during linktime it would look for the __imp_InternetOpen symbol.
The only thing that doesn't work yet is pragma(lib, "kernel32.dll");
So what you should actually request is pragma(lib, "kernel32.dll") to be 
implemented. Although the only way this could work is, that the compiler 
actually calls implib for you (or the msvc equivalent) and then actually 
links against that. The issue that ketmar originally had would remain 
though, this would only work with libraries that behave nicely and don't 
change function mangling in their import library. (like wininet does)



More information about the Digitalmars-d mailing list