www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Optional name mangling

reply "Stuart" <stugol gmx.com> writes:
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?
Jul 21 2012
next sibling parent reply =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <alex lycus.org> writes:
On 21-07-2012 21:24, 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?

Shouldn't you be using extern (Windows) ? -- Alex Rønne Petersen alex lycus.org http://lycus.org
Jul 21 2012
parent Mike Parker <aldacron gmail.com> writes:
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
Jul 21 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, July 21, 2012 21:56:36 Alex R=C3=B8nne Petersen wrote:
 On 21-07-2012 21:24, Stuart wrote:
 Hi. Is there any way to instruct the D compiler not to use name man=


 when referencing an external C++ function?
=20
 For example:
     extern (System) bool PathRenameExtension(LPSTR pszPath, LPCSTR
     pszExt);
=20
 In this particular case, the exported function being referenced is =


 called _PathRenameExtension 8 - it's just called PathRenameExtensio=


 Now, it's great that D helpfully mangles the name for me when
 appropriate, but we really need some way to disable it when necessa=


=20
 Is there any way to import this function without creating a .def fi=


 with "_PathRenameExtension 8 =3D PathRenameExtension"? And if not, =


=20
 Shouldn't you be using extern (Windows) ?

extern(System) should be fine in that it's the same as extern(Windows) = on=20 Windows, but since it's a Windows-specific function, it probably _shoul= d_ be=20 using extern(Windows). Of course, since PathRenameExtensions does what std.path.setExtension d= oes, it=20 would probably be better to just use that, but the OP's question _does_= apply=20 to other functions which may not have D replacements, so the question i= s still=20 relevant. - Jonathan M Davis
Jul 21 2012
prev sibling next sibling parent "Stuart" <stugol gmx.com> writes:
On Saturday, 21 July 2012 at 19:56:37 UTC, Alex Rønne Petersen 
wrote:
 Shouldn't you be using extern (Windows) ?

Yeah. I changed it to (System) in the hope it'd try *not* mangling the name; and didn't bother changing it back when I discovered it didn't help. The language (which, let me say, is looking pretty damn good!) really, desperately needs an "extern(C)" keyword. I mean, like, yesterday!
Jul 21 2012
prev sibling next sibling parent "Stuart" <stugol gmx.com> writes:
On Saturday, 21 July 2012 at 20:07:00 UTC, Jonathan M Davis wrote:
 Of course, since PathRenameExtensions does what 
 std.path.setExtension does, it
 would probably be better to just use that, but the OP's 
 question _does_ apply
 to other functions which may not have D replacements, so the 
 question is still
 relevant.

I didn't know about std.path.setExtension. Is there some kind of table where I can look up D equivalents to API function calls? 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)
Jul 21 2012
prev sibling next sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Saturday, 21 July 2012 at 21:17:17 UTC, Stuart wrote:
 The language (which, let me say, is looking pretty damn good!) 
 really, desperately needs an "extern(C)" keyword. I mean, like, 
 yesterday!

extern(C) exists … and we couldn't even have made it to "yesterday" without it. David
Jul 21 2012
prev sibling next sibling parent "JImmy Cao" <jcao219 gmail.com> writes:
On Saturday, 21 July 2012 at 21:17:17 UTC, Stuart wrote:
 On Saturday, 21 July 2012 at 19:56:37 UTC, Alex Rønne Petersen 
 wrote:
 Shouldn't you be using extern (Windows) ?

Yeah. I changed it to (System) in the hope it'd try *not* mangling the name; and didn't bother changing it back when I discovered it didn't help. The language (which, let me say, is looking pretty damn good!) really, desperately needs an "extern(C)" keyword. I mean, like, yesterday!

D already has extern(C).
Jul 21 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, July 21, 2012 23:18:46 Stuart wrote:
 On Saturday, 21 July 2012 at 20:07:00 UTC, Jonathan M Davis wrote:
 Of course, since PathRenameExtensions does what
 std.path.setExtension does, it
 would probably be better to just use that, but the OP's
 question _does_ apply
 to other functions which may not have D replacements, so the
 question is still
 relevant.

I didn't know about std.path.setExtension. Is there some kind of table where I can look up D equivalents to API function calls?

No. If you want to know what's there, you need to look at the documentation. For the most part, the module names are reasonbly well named after what they do, so you should be able to figure out what module contains the functionality you're looking for without too much difficulty. As for this case, Path-related stuff goes in std.path, stuff that operates on a file as a whole is in std.file, and stuff that involves more general I/O (including reading a file in pieces) is in std.stdio. - Jonathan M Davis
Jul 21 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, July 21, 2012 23:17:16 Stuart wrote:
 On Saturday, 21 July 2012 at 19:56:37 UTC, Alex R=C3=B8nne Petersen
=20
 wrote:
 Shouldn't you be using extern (Windows) ?

Yeah. I changed it to (System) in the hope it'd try *not* mangling the name; and didn't bother changing it back when I discovered it didn't help. =20 The language (which, let me say, is looking pretty damn good!) really, desperately needs an "extern(C)" keyword. I mean, like, yesterday!

http://dlang.org/interfaceToC.html http://dlang.org/cpp_interface.html http://dlang.org/htomodule.html - Jonathan M Davis
Jul 21 2012
prev sibling next sibling parent "Stuart" <stugol gmx.com> writes:
On Saturday, 21 July 2012 at 21:25:29 UTC, JImmy Cao wrote:
 On Saturday, 21 July 2012 at 21:17:17 UTC, Stuart wrote:
 On Saturday, 21 July 2012 at 19:56:37 UTC, Alex Rønne 
 Petersen wrote:
 Shouldn't you be using extern (Windows) ?

Yeah. I changed it to (System) in the hope it'd try *not* mangling the name; and didn't bother changing it back when I discovered it didn't help. The language (which, let me say, is looking pretty damn good!) really, desperately needs an "extern(C)" keyword. I mean, like, yesterday!

D already has extern(C).

Well, yes and no: extern (C) bool PathRenameExtension(LPSTR pszPath, LPCSTR pszExt); Attempts to bind to a function called _PathRenameExtension. Which is, naturally, of no use whatsoever.
Jul 21 2012
prev sibling next sibling parent "Stuart" <stugol gmx.com> writes:
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.
Jul 21 2012
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
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."
Jul 21 2012
prev sibling next sibling parent "Stuart" <stugol gmx.com> writes:
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) ---
Jul 21 2012
prev sibling next sibling parent "JImmy Cao" <jcao219 gmail.com> writes:
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
Jul 21 2012
prev sibling next sibling parent Mike Parker <aldacron gmail.com> writes:
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.
Jul 21 2012
prev sibling next sibling parent reply "Daniel Murphy" <yebblies nospamgmail.com> writes:
"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.
Jul 21 2012
parent reply Walter Bright <newshound2 digitalmars.com> writes:
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.
Jul 22 2012
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2012-07-22 15:12, Stuart wrote:

 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?

I used it a couple of weeks ago and it worked. -- /Jacob Carlborg
Jul 22 2012
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/22/2012 6:12 AM, Stuart wrote:
 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 agree, it's a pain, and a pointless one at that.
 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?

There's no magical way for implib to figure out what the nn in nn must be.
Jul 22 2012
parent "Daniel Murphy" <yebblies nospamgmail.com> writes:
"Stuart" <stugol gmx.com> wrote in message 
news:hcrszoaeyauztrlpifgu forum.dlang.org...
 Correct me if I'm wrong, but isn't it only C++ that does mangling?

You're wrong.
Jul 23 2012
prev sibling next sibling parent "Stuart" <stugol gmx.com> writes:
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.
Jul 22 2012
prev sibling next sibling parent "Stuart" <stugol gmx.com> writes:
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?
Jul 22 2012
prev sibling next sibling parent Sean Kelly <sean invisibleduck.org> writes:
On Jul 22, 2012, at 6:12 AM, "Stuart" <stugol gmx.com> wrote:

 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 Microso=


=20
   _name nn
=20
 but somehow Microsoft left off the _ and  nn in the DLLs. Hence, part of t=


me nn =3D> name.
=20
 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 manglin=

amn line in every Microsoft .def file by hand!!! Surely that's a good idea?
=20
 I don't know why implib is ignoring the /s switch, but it is. My .lib file=

t. Do I need a different version of implib or something? Shouldn't the /s sw= itch add underscores to everything? I think there's definitely some use in being able to specify a symbol name a= s a string, both for aliasing external symbols and overriding name mangling o= f internal symbols.=20=
Jul 22 2012
prev sibling next sibling parent "Stuart" <stugol gmx.com> writes:
On Monday, 23 July 2012 at 06:28:56 UTC, Jacob Carlborg wrote:
 On 2012-07-22 15:12, Stuart wrote:

 I don't know why implib is ignoring the /s switch, but it is.

I used it a couple of weeks ago and it worked.

Oh, well, I guess that makes it alright, huh? I guess I must just be an idiot, or hallucinating, yeah? Alternatively, you could take my word for it when I say it ain't working, and offer some kind of constructive advice.
Jul 23 2012
prev sibling next sibling parent "Stuart" <stugol gmx.com> writes:
On Monday, 23 July 2012 at 06:44:22 UTC, Walter Bright wrote:
 On 7/22/2012 6:12 AM, Stuart wrote:
 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 agree, it's a pain, and a pointless one at that.
 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?

There's no magical way for implib to figure out what the nn in nn must be.

Granted, but IMPLIB IS NOT PREFIXING THE NAMES WITH AN UNDERSCORE, even when used with the /s switch. Hello? Houston? Am I getting through? In any case, adding support for importing unmangled function names in D would help in these cases; and also allow us to import unmangled functions that were exported from C using the "extern C" instruction in C++. Correct me if I'm wrong, but isn't it only C++ that does mangling? As I recall, straight C doesn't support overloading and doesn't mangle names. Therefore, I reckon your "extern (C)" instruction ought instead to be written "extern (C++)", and a new "extern (C)" should be introduced that does no name mangling. Alternatively, I may be wrong, but even so, a non-mangling keyword would be helpful. And surely it wouldn't be difficult to implement?
Jul 23 2012
prev sibling next sibling parent "Stuart" <stugol gmx.com> writes:
On Monday, 23 July 2012 at 14:08:39 UTC, Daniel Murphy wrote:
 "Stuart" <stugol gmx.com> wrote in message
 news:hcrszoaeyauztrlpifgu forum.dlang.org...
 Correct me if I'm wrong, but isn't it only C++ that does 
 mangling?

You're wrong.

Fair enough. But there are still times when we need a version of "export" that doesn't mangle.
Jul 23 2012
prev sibling next sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Monday, 23 July 2012 at 17:25:43 UTC, Stuart wrote:
 Fair enough. But there are still times when we need a version 
 of "export" that doesn't mangle.

No. This is even impossible to do with some compiler backends. For example, LLVM on OS X automatically appends an underscore to the beginning of symbol names, because every C function has an »extra« underscore at the beginning there. David
Jul 23 2012
prev sibling next sibling parent "Stuart" <stugol gmx.com> writes:
On Monday, 23 July 2012 at 17:28:38 UTC, David Nadlinger wrote:
 On Monday, 23 July 2012 at 17:25:43 UTC, Stuart wrote:
 Fair enough. But there are still times when we need a version 
 of "export" that doesn't mangle.

No. This is even impossible to do with some compiler backends. For example, LLVM on OS X automatically appends an underscore to the beginning of symbol names, because every C function has an »extra« underscore at the beginning there.

I mean for importing. The functions in shlwapi.lib don't have underscores. We ought to have some kind of syntax for importing them without faffing about with .def files. Surely it must be possible?
Jul 23 2012
prev sibling next sibling parent "dnewbie" <run3 myopera.com> writes:
On Monday, 23 July 2012 at 20:57:37 UTC, Stuart wrote:
 On Monday, 23 July 2012 at 17:28:38 UTC, David Nadlinger wrote:
 On Monday, 23 July 2012 at 17:25:43 UTC, Stuart wrote:
 Fair enough. But there are still times when we need a version 
 of "export" that doesn't mangle.

No. This is even impossible to do with some compiler backends. For example, LLVM on OS X automatically appends an underscore to the beginning of symbol names, because every C function has an »extra« underscore at the beginning there.

I mean for importing. The functions in shlwapi.lib don't have underscores. We ought to have some kind of syntax for importing them without faffing about with .def files. Surely it must be possible?

Hi Stuart. If you have the Windows SDK you can run coffimplib "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib\shlwapi.lib" C:\D\dmd2\windows\lib\shlwapi.lib We could run coffimplib on *.lib from the Windows SDK and include the resulting OMF libraries on the dmd.zip package. I don't know if it is 'legal'.
Jul 23 2012
prev sibling parent "Stuart" <stugol gmx.com> writes:
On Monday, 23 July 2012 at 22:53:52 UTC, dnewbie wrote:
 If you have the Windows SDK you can run

 coffimplib "C:\Program Files (x86)\Microsoft 
 SDKs\Windows\v7.0A\Lib\shlwapi.lib" 
 C:\D\dmd2\windows\lib\shlwapi.lib

Finally! Something that works! Thank you. I had tried implib and other coff conversion tools and got nowhere.
Jul 23 2012