digitalmars.D - extern (C) private linking issue
- William R. DeVore (37/37) Feb 25 2007 I am running into an issue under windows during linking.
- Derek Parnell (19/64) Feb 25 2007 I'll have a go at this one, but I'm just guessing...
- Frits van Bommel (9/35) Feb 26 2007 Pretty good guess ;).
- Will DeVore (Quartz) (4/6) Feb 26 2007 Frits van Bommel Wrote:
- Frits van Bommel (13/15) Feb 26 2007 It _doesn't_ work. Both functions are put in section
- William R. DeVore (2/5) Feb 26 2007 Thanks Frits for clearing that up for me. I didn't realize that was happ...
I am running into an issue under windows during linking. I am getting an optlink error based on a private function in a module: [quote] C:\Working\D1.0\Derelict228\examples\graphical>build simulation -full Using Double Precision OPTLINK (R) for Win32 Release 7.50B1 Copyright (C) Digital Mars 1989 - 2001 All Rights Reserved Simulations\CylBoxSlide.obj(CylBoxSlide) Offset 01494H Record Type 00C3 Error 1: Previous Definition Different : _collisionCallback [/quote] File CylVsSphere.d has: [code] extern (C) private void collisionCallback(void* data, dGeomID o1, dGeomID o2) { ... } [/code] and CylBoxSlide.d has: [code] extern (C) private void collisionCallback(void* data, dGeomID o1, dGeomID o2) { ... } [/code] Doesn't the private attribute hide the functions? These modules are imported in a factory module (SimFactory.d) as so: [code] module Simulations.SimFactory; import Simulations.ISimulation; import Simulations.CylVsSphere; import Simulations.CylBoxSlide; ... [/code] Linux linker respects the scope but window doesn't. I am using dmd 1.007 Any suggestions? Should I submit a bugzilla? I really don't want to have a unique name for each collision callback function inside a module if I can avoid it. Thks. -Will (Quartz) quartz13163 at distanthumans dot info
Feb 25 2007
On Sun, 25 Feb 2007 23:33:25 -0500, William R. DeVore wrote:I am running into an issue under windows during linking. I am getting an optlink error based on a private function in a module: [quote] C:\Working\D1.0\Derelict228\examples\graphical>build simulation -full Using Double Precision OPTLINK (R) for Win32 Release 7.50B1 Copyright (C) Digital Mars 1989 - 2001 All Rights Reserved Simulations\CylBoxSlide.obj(CylBoxSlide) Offset 01494H Record Type 00C3 Error 1: Previous Definition Different : _collisionCallback [/quote] File CylVsSphere.d has: [code] extern (C) private void collisionCallback(void* data, dGeomID o1, dGeomID o2) { ... } [/code] and CylBoxSlide.d has: [code] extern (C) private void collisionCallback(void* data, dGeomID o1, dGeomID o2) { ... } [/code] Doesn't the private attribute hide the functions? These modules are imported in a factory module (SimFactory.d) as so: [code] module Simulations.SimFactory; import Simulations.ISimulation; import Simulations.CylVsSphere; import Simulations.CylBoxSlide; ... [/code] Linux linker respects the scope but window doesn't. I am using dmd 1.007 Any suggestions? Should I submit a bugzilla? I really don't want to have a unique name for each collision callback function inside a module if I can avoid it.I'll have a go at this one, but I'm just guessing... The 'private' qualifier does "hide" is from the compiler's point of view. But it is not so much "hiding" as "preventing access". That is, the compiler will stop code in one module from trying to call a private function in another module. The "extern (C)" qualifier stops the compiler from mangling the name. Without this qualifier, the compiler adds the module name, and the argument signature to the name of a function in the object file. That means that two functions with the same name, but in different modules get different linkage names. However, by using "extern (C)" you override that so that each module's object file will contain the same linkage name. Why do you need to specify "extern (C)"? -- Derek (skype: derek.j.parnell) Melbourne, Australia "Justice for David Hicks!" 26/02/2007 4:21:48 PM
Feb 25 2007
Derek Parnell wrote:On Sun, 25 Feb 2007 23:33:25 -0500, William R. DeVore wrote:[snip]I am running into an issue under windows during linking. I am getting an optlink error based on a private function in a module:Pretty good guess ;).Linux linker respects the scope but window doesn't. I am using dmd 1.007 Any suggestions? Should I submit a bugzilla? I really don't want to have a unique name for each collision callback function inside a module if I can avoid it.I'll have a go at this one, but I'm just guessing... The 'private' qualifier does "hide" is from the compiler's point of view. But it is not so much "hiding" as "preventing access". That is, the compiler will stop code in one module from trying to call a private function in another module.The "extern (C)" qualifier stops the compiler from mangling the name. Without this qualifier, the compiler adds the module name, and the argument signature to the name of a function in the object file. That means that two functions with the same name, but in different modules get different linkage names. However, by using "extern (C)" you override that so that each module's object file will contain the same linkage name. Why do you need to specify "extern (C)"?Seeing the word "callback" so often makes me think he probably uses these functions for use as a callback (function pointer) passed to a C API. So he needs them to use the C calling convention, which they will use when declared extern(C). I have also on occasion wanted to specify calling convention without specifying mangling, but current D doesn't offer that possibility :(.
Feb 26 2007
Frits van Bommel Wrote: I should have explained the environment a bit better, but Frits you are correct. I am experiencing this using ODE.org. When a collision occurs ODE calls back to the D code. The callback needs to be defined as extern (C) otherwise D crashes when the callback completes. I was using the 'private' attribute to in the module such that it wouldn't clash with the other simulation modules that have the same function name.I have also on occasion wanted to specify calling convention without specifying mangling, but current D doesn't offer that possibility :(.I wonder why then it works under linux though. The linux linker seems to be able to identify the correct private function. I don't really know how Optlink works but I would say it is having problems making unique mangled names inside of modules with private attributes. Hmm...
Feb 26 2007
Will DeVore (Quartz) wrote:I wonder why then it works under linux though. The linux linker seems to be able to identify the correct private function.It _doesn't_ work. Both functions are put in section .gnu.linkonce.ttext, which means the linker will throw away one of them and silently use the other in its place. In this case, I prefer Optlink behavior.I don't really know how Optlink works but I would say it is havingproblems making unique mangled names inside of modules with private attributes. Hmm... No, Optlink does exactly what it should do in this instance. _DMD_ has problems making unique mangled names of extern(C) functions. The main problem being that it's not allowed to do so :P. 'extern(C)' means it has to use the C mangling as well as the C calling convention, and C mangling means no mangling at all (except, on Windows, a leading '_' -- not much help).
Feb 26 2007
Frits van Bommel Wrote:It _doesn't_ work. Both functions are put in section .gnu.linkonce.ttext, which means the linker will throw away one of them ...Thanks Frits for clearing that up for me. I didn't realize that was happening. :)
Feb 26 2007