February 11, 2013
On Sun, 10 Feb 2013 12:36:38 -0000, Ben Davis <entheh@cantab.net> wrote:

> On 10/02/2013 08:17, Benjamin Thaut wrote:
>> Am 10.02.2013 03:03, schrieb Ben Davis:
>>>
>>> My functions are "export extern (Windows)" - I think they're global...?
>>>
>>> For example:
>>>
>>> export extern(Windows) LRESULT DriverProc(DWORD_PTR dwDriverId, HDRVR
>>> hdrvr, UINT msg, LONG lParam1, LONG lParam2) nothrow { ... }
>>
>> Do you have a copy of visual studio around? If so you can use
>> dumpbin /EXPORTS your.dll
>>  From a visual studio command shell to see the symbols the dll actually
>> exports. Just compare the version where you manually listed them in the
>> exports section with the version where you don't manually list exports.
>
> Thanks, that helped expose what's going on.
>
> With the def, I get lines like "DriverProc = _DriverProc@20".
> Without it, I get lines like "_DriverProc@20 = _DriverProc@20".
> So the difference is that the export is done under a slightly mangled name if I only mark it in the code, and I need to use the def file to specify the exact name to export by. I suppose this is only necessary for weird things like driver entry points, and not for normal exported functions.
>
> A bit more Googling reveals that the @n is the number of bytes taken by arguments, and is part of the stdcall == extern(Windows) convention. So Windows is making me use stdcall and then making me throw that information away in the export table. But hey - it wouldn't be the worst thing I've encountered with the Windows API. (._.'|||| :P)

Some more background info:
http://en.wikipedia.org/wiki/Name_mangling

> DllMain is a weird one - it creates all sorts of linker errors if I try it with extern(C) instead of extern(Windows) (which is different from the other methods, which compile fine with extern(C) and then crash at runtime).

extern(C) will change the mangling.. so in this case I guess the linker is expecting DllMain but the mangling is incorrect.  I wonder if the compiler detects the presence of DllMain and alters the linker line.  DMD has a command line option to output the linker command line, maybe see if it changes with/without a DllMain in the code perhaps.

> Also it doesn't matter what name I export it by or whether I export it at all. I'm getting the feeling this is what was implied by "The presence of DllMain() is recognized by the compiler". Good to know anyway - I like to keep stuff clean :)

Yep, DllMain isn't a requirement, but if is present should be called by the C runtime when the dll is loaded.  You can hook into process start/stop and thread attach/detach with dll main.  It's good for thread local storage initialisation - for example.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
February 16, 2013
On 11/02/2013 16:06, Regan Heath wrote:
> On Sun, 10 Feb 2013 12:36:38 -0000, Ben Davis <entheh@cantab.net> wrote:
>> DllMain is a weird one - it creates all sorts of linker errors if I
>> try it with extern(C) instead of extern(Windows) (which is different
>> from the other methods, which compile fine with extern(C) and then
>> crash at runtime).
>
> extern(C) will change the mangling.. so in this case I guess the linker
> is expecting DllMain but the mangling is incorrect.  I wonder if the
> compiler detects the presence of DllMain and alters the linker line.
> DMD has a command line option to output the linker command line, maybe
> see if it changes with/without a DllMain in the code perhaps.

I think that's exactly what's going on. If it was only the mangling, I'd expect one error relating to that function, but instead I get at least 10 errors relating to various functions I've never heard of. I don't think there's any particular need to test further.

>> Also it doesn't matter what name I export it by or whether I export it
>> at all. I'm getting the feeling this is what was implied by "The
>> presence of DllMain() is recognized by the compiler". Good to know
>> anyway - I like to keep stuff clean :)
>
> Yep, DllMain isn't a requirement, but if is present should be called by
> the C runtime when the dll is loaded.  You can hook into process
> start/stop and thread attach/detach with dll main.  It's good for thread
> local storage initialisation - for example.

Yep, sounds about right - and it sounds like something that gets resolved in a special way when the DLL is linked. Certainly DllMain isn't appearing in my export table, yet I've established (by calling MessageBoxA from inside DllMain - that was brave of me, wasn't it? :P) that it is being called. :)
February 16, 2013
On 2/16/13, Ben Davis <entheh@cantab.net> wrote:
> Certainly DllMain
> isn't appearing in my export table, yet I've established (by calling
> MessageBoxA from inside DllMain - that was brave of me, wasn't it? :P)
> that it is being called. :)

It's handled by the compiler itself, e.g.: https://github.com/D-Programming-Language/dmd/blob/master/src/backend/out.c#L1256
1 2
Next ›   Last »