Jump to page: 1 2
Thread overview
extern(Windows, "user32.dll")
Feb 01, 2015
Vladimir Panteleev
Feb 01, 2015
Rikki Cattermole
Feb 01, 2015
Vladimir Panteleev
Feb 01, 2015
Rikki Cattermole
Feb 01, 2015
Daniel Murphy
Feb 01, 2015
Benjamin Thaut
Feb 01, 2015
Vladimir Panteleev
Feb 01, 2015
Benjamin Thaut
Feb 01, 2015
Vladimir Panteleev
Feb 01, 2015
Benjamin Thaut
Feb 01, 2015
Vladimir Panteleev
Feb 01, 2015
Benjamin Thaut
Feb 01, 2015
Vladimir Panteleev
Feb 01, 2015
Benjamin Thaut
Feb 01, 2015
Vladimir Panteleev
February 01, 2015
The Delphi programming language allows specifying the DLL name right on the declaration of extern symbols:

function GetVersion: DWORD; stdcall; external 'kernel32.dll';

I would like to suggest adding something similar to D:

extern(Windows, "kernel32.dll") DWORD GetVersion();

Rationale:

This absolves the need for import libraries.

* Import libraries are a major and unnecessary pain in the neck when using DLLs of any kind.

* Import libraries may need conversion from COFF format to OMF format with a tool which is not included with D (coffimplib).

* Import libraries can *sometimes* be created from the DLL using implib, but this does not always work, depending on the calling convention and its mangling.

* Name mangling mismatches are difficult to diagnose.

* Import libraries cannot be used with tools such as "rdmd", except via pragma(lib).

Any thoughts? DIP or not?
February 01, 2015
On 1/02/2015 11:26 p.m., Vladimir Panteleev wrote:
> The Delphi programming language allows specifying the DLL name right on
> the declaration of extern symbols:
>
> function GetVersion: DWORD; stdcall; external 'kernel32.dll';
>
> I would like to suggest adding something similar to D:
>
> extern(Windows, "kernel32.dll") DWORD GetVersion();
>
> Rationale:
>
> This absolves the need for import libraries.
>
> * Import libraries are a major and unnecessary pain in the neck when
> using DLLs of any kind.
>
> * Import libraries may need conversion from COFF format to OMF format
> with a tool which is not included with D (coffimplib).
>
> * Import libraries can *sometimes* be created from the DLL using implib,
> but this does not always work, depending on the calling convention and
> its mangling.
>
> * Name mangling mismatches are difficult to diagnose.
>
> * Import libraries cannot be used with tools such as "rdmd", except via
> pragma(lib).
>
> Any thoughts? DIP or not?

How about:

extern(System, "mylibrary"):

That way it'll be a bit more cross platform'ish.
February 01, 2015
"Vladimir Panteleev"  wrote in message news:kksyjkgkwdfqfwhqwldb@forum.dlang.org...

> extern(Windows, "kernel32.dll") DWORD GetVersion();

export would be a better fit than extern, or a pragma.  It's probably a good idea to check that all object formats can actually handle an impdef in a normal object file.  IIRC you also need a way to specify undecorated names for some windows DLLs.

Seems like a good idea. 

February 01, 2015
On Sunday, 1 February 2015 at 10:34:05 UTC, Rikki Cattermole wrote:
> How about:
>
> extern(System, "mylibrary"):
>
> That way it'll be a bit more cross platform'ish.

DLLs can have any extension. Many Windows components that don't have a .exe or .dll extension are actually PE files.

You should be able to define the library as a constant, e.g.:

enum user32 = "user32.dll";

extern(Windows, user32) DWORD MessageBox(...);

This is also what Delphi does.

Then you can put the enum in version(...) blocks.
February 01, 2015
Am 01.02.2015 um 11:26 schrieb Vladimir Panteleev:
> The Delphi programming language allows specifying the DLL name right on
> the declaration of extern symbols:
>
> function GetVersion: DWORD; stdcall; external 'kernel32.dll';
>
> I would like to suggest adding something similar to D:
>
> extern(Windows, "kernel32.dll") DWORD GetVersion();
>
> Rationale:
>
> This absolves the need for import libraries.
>
> * Import libraries are a major and unnecessary pain in the neck when
> using DLLs of any kind.
>
> * Import libraries may need conversion from COFF format to OMF format
> with a tool which is not included with D (coffimplib).
>
> * Import libraries can *sometimes* be created from the DLL using implib,
> but this does not always work, depending on the calling convention and
> its mangling.
>
> * Name mangling mismatches are difficult to diagnose.
>
> * Import libraries cannot be used with tools such as "rdmd", except via
> pragma(lib).
>
> Any thoughts? DIP or not?

Please no. Import libraries are the way it was designed and it should be used that way. I'm currently implementing D-Dll support for Windows with dmd and without import libraries it will never work.

Also what you are proposing could easily be implemented by a library. E.g.

@dllimport("kernel32.dll") extern(Windows) DWORD GetVersion();
mixin DllImportFunctions;

Where DllImportFunctions would iterate over all symbols in the module, look for the UDA dllimport and then attemp to load the Dll and import the function.

Kind Regards
Benjamin Thaut

February 01, 2015
On 1/02/2015 11:36 p.m., Vladimir Panteleev wrote:
> On Sunday, 1 February 2015 at 10:34:05 UTC, Rikki Cattermole wrote:
>> How about:
>>
>> extern(System, "mylibrary"):
>>
>> That way it'll be a bit more cross platform'ish.
>
> DLLs can have any extension. Many Windows components that don't have a
> .exe or .dll extension are actually PE files.
>
> You should be able to define the library as a constant, e.g.:
>
> enum user32 = "user32.dll";
>
> extern(Windows, user32) DWORD MessageBox(...);
>
> This is also what Delphi does.
>
> Then you can put the enum in version(...) blocks.

I see, reasonable.
February 01, 2015
On Sunday, 1 February 2015 at 10:40:06 UTC, Benjamin Thaut wrote:
> Please no. Import libraries are the way it was designed

Delphi does without them just fine.

> and it should be used that way.

Why? It seems to me like they are a historical artifact. I don't see any merit in the design, none at all. Linux does away with them because ld can link against .so, but OPTLINK can't link against .dll files (although UniLink can).

> I'm currently implementing D-Dll support for Windows with dmd and without import libraries it will never work.

Why? I'm not suggesting to remove import library support.

> Also what you are proposing could easily be implemented by a library. E.g.
>
> @dllimport("kernel32.dll") extern(Windows) DWORD GetVersion();
> mixin DllImportFunctions;
>
> Where DllImportFunctions would iterate over all symbols in the module, look for the UDA dllimport and then attemp to load the Dll and import the function.

Dynamic loading delays the error until execution time, instead of link time, and is slower.
February 01, 2015
On Sunday, 1 February 2015 at 10:26:25 UTC, Vladimir Panteleev wrote:
> Rationale:

Another data point, apparently MinGW doesn't need import libraries either, if you specify `--enable-auto-import --enable-stdcall-fixup`.
February 01, 2015
Am 01.02.2015 um 11:45 schrieb Vladimir Panteleev:
> On Sunday, 1 February 2015 at 10:40:06 UTC, Benjamin Thaut wrote:
>> Please no. Import libraries are the way it was designed
>
> Delphi does without them just fine.

C++ does with them just fine.

>
>> I'm currently implementing D-Dll support for Windows with dmd and
>> without import libraries it will never work.
>
> Why? I'm not suggesting to remove import library support.

I don't care what you are suggesting. If you want a implementation of Dll support without import libraries do it yourself. And lets just say it is required to link against druntime correctly. I don't want to give you a 4 page text explanation why.

>
> Dynamic loading delays the error until execution time, instead of link
> time, and is slower.

I hardly doubt that. If you link against a dll the windows binary loader is just doing the work for you. But the symbols are looked up in the dll by string either way.

Also, proof of concept: http://dpaste.dzfl.pl/efbd54314a69

The real issue here is, that dmd simply does not come with all neccessary import libraries when using optlink. As soon as you switch to the microsoft linkers this becomes a non issue.

Kind Regards
Benjamin Thaut
February 01, 2015
On Sunday, 1 February 2015 at 11:10:21 UTC, Benjamin Thaut wrote:
> Am 01.02.2015 um 11:45 schrieb Vladimir Panteleev:
>> On Sunday, 1 February 2015 at 10:40:06 UTC, Benjamin Thaut wrote:
>>> Please no. Import libraries are the way it was designed
>>
>> Delphi does without them just fine.
>
> C++ does with them just fine.

And this is a valid argument, how?

> I don't care what you are suggesting. If you want a implementation of Dll support without import libraries do it yourself.

Nice.

> And lets just say it is required to link against druntime correctly. I don't want to give you a 4 page text explanation why.

So you expect us to just trust you, then?

I also did not say that we should replace all usage of import libraries in Druntime.

> I hardly doubt that. If you link against a dll the windows binary loader is just doing the work for you. But the symbols are looked up in the dll by string either way.

I believe this hasn't been true for a few Windows versions now. AFAIK static imports are cached by the PE loader.

Either way, a heap allocation during initialization could force a rebase.

> Also, proof of concept: http://dpaste.dzfl.pl/efbd54314a69

This is nothing new. Derelict does this. I have it implemented myself in my library.

It won't work in DLLs. You can't call LoadLibrary in DllMain. The runtime is initialized in DllMain, so static constructors run there too. Even if you defer the LoadLibrary call until the function is first called, that still leaves you the problem that the functions are unusable in static constructors.

It also won't work with TLS (i.e. all D DLLs) except on recent Windows versions.

> The real issue here is, that dmd simply does not come with all neccessary import libraries when using optlink. As soon as you switch to the microsoft linkers this becomes a non issue.

It literally *can't* come with *all* necessary import libraries.
« First   ‹ Prev
1 2