Bug 17359 – C++ Interfacing: function with 'static' array parameter cannot be linked (x64)

Status
RESOLVED
Resolution
WORKSFORME
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Windows
Creation time
2017-04-28T19:41:26Z
Last change time
2022-03-01T02:04:04Z
Keywords
C++, mangling
Assigned to
No Owner
Creator
Peter Particle

Comments

Comment #0 by ParticlePeter — 2017-04-28T19:41:26Z
C++ Interfacing: function with 'static' array parameter cannot be linked (x64) C++ prototype: bool cppFunc( float[3] color ); D binding (as described here [1]) extern(C++) bool cppFunc( ref float color ); Using with: float[3] my_color; cppFunc( my_color ); Building with dmd 2.0.73.1: -> error LNK2001: unresolved external symbol "bool __cdecl cppFunc(float (&)[3])" Binding.exe : fatal error LNK1120: 1 unresolved externals Error: linker exited with status 1120 dmd failed with exit code 1120. Same problem but slightly different error messages with LDC. The issue is discussed here in additional detail [2]. Summary: Ali mentions that following variant works for him on linux: " // deneme.cpp float cppFunc(float color[3]) { return color[0] + color[1] + color[2]; } $ g++ -c deneme.cpp -o deneme_cpp.o // deneme.d extern(C++) float cppFunc(float * color); void main() { float[3] my_color = [ 1.5, 2.5, 3.5 ] ; assert(cppFunc(my_color.ptr) == 7.5); } $ dmd deneme_cpp.o deneme.d -of=deneme " Comment: This varinat leads to the same compiler error (with "bool __cdecl cppFunc(float*)" message) on windows compiled for x64. kinke points out: " Microsoft's C++ compiler doesn't mangle `float arg[3]` parameters identically to `float* arg`: void cppSArray(float color[3]) => ?cppSArray@@YAXQEAM@Z void cppPtr(float* color) => ?cppPtr@@YAXPEAM@Z " This contradicts Alis variant but not the 'ref' variant. But I belief that the 'ref' variant is also a mangling problem. [1] http://dlang.org/spec/interfaceToC.html#passing_d_array [2] https://forum.dlang.org/post/[email protected]
Comment #1 by ParticlePeter — 2017-04-29T07:52:36Z
As a work around, we can use Ali's variant and pragma(mangle, "mangle_string"). I found my "mangle_string" with dependency walker.
Comment #2 by kinke — 2017-04-29T09:39:03Z
I think this is no DMD bug. The problem is that Microsoft unlike gcc mangles the `float color[3]` variant as `float * const color`, which can't be represented in D directly (const pointer to mutable data).
Comment #3 by kinke — 2017-04-29T09:57:19Z
So the proper workaround for MSVC targets would be: C++: bool cppFunc(float color[3]) { for (int i = 0; i < 3; ++i) color[i] *= 2; return true; } D: pragma(mangle, "?cppFunc@@YA_NQEAM@Z") extern(C++) bool cppFunc(ref float[3] color); void main() { float[3] my_color = [ 1, 2, 3 ]; cppFunc(my_color); assert(my_color == [ 2, 4, 6 ]); }
Comment #4 by bugzilla — 2018-04-10T05:38:03Z
To get the same results in C++ and D: C++: void cppFunc(float (&color)[3]) { } D: extern(C++) void cppFunc(ref float[3] color) { } Both mangle to: ?cppFunc@@YAXAAY02M@Z