Bug 22323 – Link error for virtual destructor of C++ class in DLL
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Windows
Creation time
2021-09-19T19:22:37Z
Last change time
2021-10-13T13:17:32Z
Keywords
C++, pull
Assigned to
No Owner
Creator
Tim
Comments
Comment #0 by tim.dlang — 2021-09-19T19:22:37Z
A C++ class with virtual destructor in a DLL can't be used from D, because a symbol is not found during linking.
/////////////// testdestructor.d /////////////////
extern(C++) class C
{
~this();
}
void main()
{
C o = new C;
}
///////////// testdestructorcpp.cpp //////////////
class __declspec(dllexport) C
{
public:
virtual ~C();
};
C::~C()
{
}
//////////////////////////////////////////////////
First I'm compiling a DLL from the C++ file:
cl /LD /nologo testdestructorcpp.cpp
Then I try to compile the D program using the DLL, which fails to link:
dmd -m64 testdestructor.d testdestructorcpp.lib
testdestructor.obj : error LNK2001: unresolved external symbol "public: virtual void * __cdecl C::`scalar deleting destructor'(unsigned int)" (??_GC@@UEAAPEAXI@Z)
testdestructor.exe : fatal error LNK1120: 1 unresolved externals
Error: linker exited with status 1120
It works using static linking.
In the forum I found a description of the same problem: https://forum.dlang.org/thread/[email protected]
Comment #1 by kinke — 2021-09-20T03:24:30Z
(In reply to Tim from comment #0)
> It works using static linking.
Then it looks like the MS compiler generates the symbol but doesn't export it even when exporting the class - or at least doesn't include the forwarder in the DLL import lib.
It looks like this might be solvable by removing the condition in https://github.com/dlang/dmd/blob/0bbb30aad9a782b4e9a1cbec62704240729d7864/src/dmd/clone.d#L1069, where the D compiler only defines it in case the regular destructor is defined in D as well. The symbol would most likely need to be emitted as a weak definition though to prevent conflicts when linking statically etc.
Comment #2 by tim.dlang — 2021-09-21T19:21:11Z
(In reply to kinke from comment #1)
> It looks like this might be solvable by removing the condition in
> https://github.com/dlang/dmd/blob/0bbb30aad9a782b4e9a1cbec62704240729d7864/
> src/dmd/clone.d#L1069, where the D compiler only defines it in case the
> regular destructor is defined in D as well. The symbol would most likely
> need to be emitted as a weak definition though to prevent conflicts when
> linking statically etc.
Thanks for the suggestion. It seems to work in a first test.
Comment #3 by dlang-bot — 2021-10-10T11:57:20Z
@tim-dlang created dlang/dmd pull request #13148 "fix Issue 22323: Link error for virtual destructor of C++ class in DLL" fixing this issue:
- fix Issue 22323: Link error for virtual destructor of C++ class in DLL
The new test test/dshell/dll_cxx.d is based on test/dshell/dll.d, but
builds the DLL/SO from C++ instead of D.
https://github.com/dlang/dmd/pull/13148
Comment #4 by dlang-bot — 2021-10-12T07:17:45Z
dlang/dmd pull request #13148 "fix Issue 22323: Link error for virtual destructor of C++ class in DLL" was merged into master:
- d71fd29d62bf404e887740274ee6c98e56c7bd6f by Tim Schendekehl:
fix Issue 22323: Link error for virtual destructor of C++ class in DLL
The new test test/dshell/dll_cxx.d is based on test/dshell/dll.d, but
builds the DLL/SO from C++ instead of D.
https://github.com/dlang/dmd/pull/13148
Comment #5 by dlang-bot — 2021-10-12T11:33:32Z
dlang/dmd pull request #13160 "fix Issue 22323: Link error for virtual destructor of C++ class in DLL" was merged into stable:
- 062a2f27565b8e3dabde457757742ebc3c9af8c6 by Tim Schendekehl:
fix Issue 22323: Link error for virtual destructor of C++ class in DLL
The new test test/dshell/dll_cxx.d is based on test/dshell/dll.d, but
builds the DLL/SO from C++ instead of D.
https://github.com/dlang/dmd/pull/13160
Comment #6 by dlang-bot — 2021-10-13T13:17:32Z
dlang/dmd pull request #13164 "Merge stable" was merged into master:
- 1e6217535f271fe9e6911bc1bf113df1a345a589 by Tim Schendekehl:
fix Issue 22323: Link error for virtual destructor of C++ class in DLL
The new test test/dshell/dll_cxx.d is based on test/dshell/dll.d, but
builds the DLL/SO from C++ instead of D.
https://github.com/dlang/dmd/pull/13164