July 21, 2012
On Saturday, 21 July 2012 at 21:21:41 UTC, David Nadlinger wrote:
> extern(C) exists … and we couldn't even have made it to "yesterday" without it.

Yes, but it prepends "_" to the function name.
July 21, 2012
On Saturday, 21 July 2012 at 22:38:32 UTC, Stuart wrote:
> Attempts to bind to a function called _PathRenameExtension. Which is, naturally, of no use whatsoever.

That is the norm on Windows though:

http://en.wikipedia.org/wiki/Name_mangling#C_name_decoration_in_Microsoft_Windows

If you're using implib on a DLL to make a .lib for D though,
the /S switch might help:
http://www.digitalmars.com/ctg/implib.html
"Prepend '_' to exported internal names."
July 21, 2012
On Saturday, 21 July 2012 at 22:51:14 UTC, Adam D. Ruppe wrote:
> On Saturday, 21 July 2012 at 22:38:32 UTC, Stuart wrote:
>> Attempts to bind to a function called _PathRenameExtension. Which is, naturally, of no use whatsoever.
>
> That is the norm on Windows though:

Granted. But not everyone's exported functions are prefixed with an underscore. I've written DLLs myself using __dllexport, and they've been named normally. It'd just be helpful to have the option, y'know?

> If you're using implib on a DLL to make a .lib for D though,
> the /S switch might help:
> http://www.digitalmars.com/ctg/implib.html
> "Prepend '_' to exported internal names."

I'm sorry, but the /S (or /system) switch doesn't seem to do anything. I still get non-underscore-prefixed output in my .lib file. I opened it in a hex editor to verify this; and D says "Error 42: Symbol Undefined _PathRenameExtension".

Do I need a different copy of implib, maybe? When I call it with /?, I get:

---
Digital Mars Import Library Manager Version 7.6B1n
Copyright (C) Digital Mars 2000.  All Rights Reserved.
Usage:
        IMPLIB [switches] implibname.lib [ file.dll | file.def ]
switches:
        /?      Print this message
        /b      Batch
        /h      Print this message
        /i      Ignore case of symbols
        /noi    Be case sensitive. Mark library as case sensitive
        /nowep  Ignore WEP
        /p:number       Set page size to number (a power of 2)
        /system         Prepend '_' to exported internal names (NT system DLL)
---

July 22, 2012
On Saturday, 21 July 2012 at 23:53:01 UTC, Stuart wrote:
> On Saturday, 21 July 2012 at 22:51:14 UTC, Adam D. Ruppe wrote:
>> On Saturday, 21 July 2012 at 22:38:32 UTC, Stuart wrote:
>>> Attempts to bind to a function called _PathRenameExtension. Which is, naturally, of no use whatsoever.
>>
>> That is the norm on Windows though:
>
> Granted. But not everyone's exported functions are prefixed with an underscore. I've written DLLs myself using __dllexport, and they've been named normally. It'd just be helpful to have the option, y'know?
>
>> If you're using implib on a DLL to make a .lib for D though,
>> the /S switch might help:
>> http://www.digitalmars.com/ctg/implib.html
>> "Prepend '_' to exported internal names."
>
> I'm sorry, but the /S (or /system) switch doesn't seem to do anything. I still get non-underscore-prefixed output in my .lib file. I opened it in a hex editor to verify this; and D says "Error 42: Symbol Undefined _PathRenameExtension".
>
> Do I need a different copy of implib, maybe? When I call it with /?, I get:
>
> ---
> Digital Mars Import Library Manager Version 7.6B1n
> Copyright (C) Digital Mars 2000.  All Rights Reserved.
> Usage:
>         IMPLIB [switches] implibname.lib [ file.dll | file.def ]
> switches:
>         /?      Print this message
>         /b      Batch
>         /h      Print this message
>         /i      Ignore case of symbols
>         /noi    Be case sensitive. Mark library as case sensitive
>         /nowep  Ignore WEP
>         /p:number       Set page size to number (a power of 2)
>         /system         Prepend '_' to exported internal names (NT system DLL)
> ---

Use either /s or /system
July 22, 2012
On 7/22/2012 6:18 AM, Stuart wrote:

> In any event, yes, my question is still relevant. What if I want to call
> some other API function? Or OpenGL? Or something I wrote in C++ with
> "extern(C)" linkage? (Something I do from time to time)

The Deimos project[1] provides a number of bindings to C libraries in a manner that requires compile-time linkage (using static libraries or import libraries as the case may be). Derelict[2] is a set of bindings to C libraries (including OpenGL) that loads the libraries at runtime (via LoadLibrary on Windows and dlopen elsewhere).

[1] https://github.com/D-Programming-Deimos
[2] https://github.com/aldacron/Derelict3
July 22, 2012
On 7/22/2012 4:24 AM, Stuart wrote:
> Hi. Is there any way to instruct the D compiler not to use name mangling
> when referencing an external C++ function?
>
> For example:
>
>     extern (System) bool PathRenameExtension(LPSTR pszPath, LPCSTR pszExt);
>
> In this particular case, the exported function being referenced is not
> called _PathRenameExtension@8 - it's just called PathRenameExtension.
> Now, it's great that D helpfully mangles the name for me when
> appropriate, but we really need some way to disable it when necessary.
>
> Is there any way to import this function without creating a .def file
> with "_PathRenameExtension@8 = PathRenameExtension"? And if not, why not?

extern(System) is extern(Windows) on Windows and extern(C) everywhere else.

extern(Windows) is stdcall, which is the Win32 API calling convention. stdcall function names are mangled to _funcName@N. So extern(System) is doing the right thing here.

What's odd is that your PathRenameExtension isn't mangled.
July 22, 2012
"Stuart" <stugol@gmx.com> wrote in message news:hmapfdehxvvuuxswrtyb@forum.dlang.org...
> Hi. Is there any way to instruct the D compiler not to use name mangling when referencing an external C++ function?
>
> For example:
>
>    extern (System) bool PathRenameExtension(LPSTR pszPath, LPCSTR pszExt);
>
> In this particular case, the exported function being referenced is not called _PathRenameExtension@8 - it's just called PathRenameExtension. Now, it's great that D helpfully mangles the name for me when appropriate, but we really need some way to disable it when necessary.
>
> Is there any way to import this function without creating a .def file with "_PathRenameExtension@8 = PathRenameExtension"? And if not, why not?

The problem isn't that D is mangling names it shouldn't, the problem is that your import library uses the wrong mangling for the internal names of imported symbols.  Using the .def file with implib is the correct solution, unless you want to try converting a coff import library to omf (I've never got that to work).  The reason implib needs a def file to work correctly is because only the exported name is stored in the dll, not the mangled name.


July 22, 2012
On 7/21/2012 11:45 PM, Daniel Murphy wrote:
> The problem isn't that D is mangling names it shouldn't, the problem is that
> your import library uses the wrong mangling for the internal names of
> imported symbols.  Using the .def file with implib is the correct solution,
> unless you want to try converting a coff import library to omf (I've never
> got that to work).  The reason implib needs a def file to work correctly is
> because only the exported name is stored in the dll, not the mangled name.

This is a very old issue. To be compatible with the output of the Microsoft C compiler, the Windows calling convention is:

   _name@nn

but somehow Microsoft left off the _ and @nn in the DLLs. Hence, part of the whole reason for the import libraries is then to provide a mapping of _name@nn => name.

I have no idea who made this decision and why, but we're stuck with it.


July 22, 2012
On Sunday, 22 July 2012 at 02:06:37 UTC, JImmy Cao wrote:
> Use either /s or /system

Yes, but - at least with the version of implib I'm using - it has no effect.
July 22, 2012
On Sunday, 22 July 2012 at 07:01:50 UTC, Walter Bright wrote:
> This is a very old issue. To be compatible with the output of the Microsoft C compiler, the Windows calling convention is:
>
>    _name@nn
>
> but somehow Microsoft left off the _ and @nn in the DLLs. Hence, part of the whole reason for the import libraries is then to provide a mapping of _name@nn => name.
>
> I have no idea who made this decision and why, but we're stuck with it.

Okay, but if you had a keyword - say, "extern(rawC)" - that did no mangling whatsoever, then I could run implib without manually editing every single damn line in every Microsoft .def file by hand!!! Surely that's a good idea?

I don't know why implib is ignoring the /s switch, but it is. My .lib file doesn't have underscores, and there doesn't seem to be much I can do about it. Do I need a different version of implib or something? Shouldn't the /s switch add underscores to everything?