digitalmars.D.learn - C++ Interfacing:'static' array function parameter contradiction
- ParticlePeter (24/24) Apr 28 2017 C++ Function:
- Kagamin (1/1) Apr 28 2017 Report a bug.
- kinke (17/18) Apr 28 2017 *** C++:
- ParticlePeter (5/23) Apr 28 2017 The c++ lib is not mine and your answer implies extra work on the
- =?UTF-8?Q?Ali_=c3=87ehreli?= (19/27) Apr 28 2017 That part is a bug at least in the compiler message. Is it really an
- ParticlePeter (5/37) Apr 28 2017 Interesting, your example corresponds to my third case, the
- kinke (5/9) Apr 28 2017 Apparently Microsoft's C++ compiler doesn't mangle `float arg[3]`
- Atila Neves (4/13) Apr 28 2017 The worst part about that is mangling aside, the two declarations
- ParticlePeter (9/24) Apr 28 2017 In this context, can anybody explain [1], in particular, in this
- Atila Neves (4/20) Apr 29 2017 It's "just" the mangling. If it were `extern(C)` there'd be
- ParticlePeter (3/27) Apr 29 2017 O.k. got it, so both D variants work with the same C++ mangling,
- ParticlePeter (7/39) Apr 28 2017 Btw, according to [1] your example should not work either, I
- Nicholas Wilson (8/56) Apr 28 2017 If you are having problems with the linker with Ali's you can do
- ParticlePeter (5/12) Apr 29 2017 Thanks for that hint! I got it to work. Side note,
- =?UTF-8?B?2LPZhNmK2YXYp9mGINin2YTYs9mH?= (4/20) Apr 29 2017 But still, this needs to be fixed, copy pasting the name mangling
- kinke (13/16) Apr 29 2017 It can't be fixed on the D side as the Visual C++ mangling of
C++ Function: bool cppFunc( float[3] color ); D binding: extern(C++) bool cppFunc( float[3] color ); Using with: float[3] my_color; cppFunc( my_color ); -> Error: Internal Compiler Error: unable to pass static array to extern(C++) function. Error: Use pointer instead. Using with: cppFunc( my_color.ptr ); -> Error: function cppFunc( float[3] color ) is not callable using argument types (float*) Altering D binding: extern(C++) bool cppFunc( float* color ); Using with: cppFunc( my_color.ptr ); -> error LNK2001: unresolved external symbol "bool __cdecl cppFunc(float *)" Binding.exe : fatal error LNK1120: 1 unresolved externals Error: linker exited with status 1120 dmd failed with exit code 1120. So what next? How can I interface to the cpp function?
Apr 28 2017
On Friday, 28 April 2017 at 15:56:17 UTC, ParticlePeter wrote:So what next? How can I interface to the cpp function?*** C++: bool cppFunc(float (&color)[3]) { color[0] = 1; color[1] = 2; color[2] = 3; return true; } *** D: extern(C++) bool cppFunc(ref float[3] color); void main() { float[3] my_color; cppFunc(my_color); assert(my_color == [ 1, 2, 3 ]); }
Apr 28 2017
On Friday, 28 April 2017 at 17:15:54 UTC, kinke wrote:On Friday, 28 April 2017 at 15:56:17 UTC, ParticlePeter wrote:The c++ lib is not mine and your answer implies extra work on the c++ from my side. Possible, but not desired, I think calling my original c++ function should interface with an d pointer. That being said, I think Kagamin is right.So what next? How can I interface to the cpp function?*** C++: bool cppFunc(float (&color)[3]) { color[0] = 1; color[1] = 2; color[2] = 3; return true; } *** D: extern(C++) bool cppFunc(ref float[3] color); void main() { float[3] my_color; cppFunc(my_color); assert(my_color == [ 1, 2, 3 ]); }
Apr 28 2017
On 04/28/2017 08:56 AM, ParticlePeter wrote:C++ Function: bool cppFunc( float[3] color ); D binding: extern(C++) bool cppFunc( float[3] color ); Using with: float[3] my_color; cppFunc( my_color ); -> Error: Internal Compiler Error: unable to pass static array toThat part is a bug at least in the compiler message. Is it really an internal ctompiler error? Doesn't look like it: the compiler is talking to us happily. :) My simple test works for me: // 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 Builds and runs fine... on Linux... I don't know whether that's significant. Ali
Apr 28 2017
On Friday, 28 April 2017 at 17:57:34 UTC, Ali Çehreli wrote:On 04/28/2017 08:56 AM, ParticlePeter wrote:Interesting, your example corresponds to my third case, the linker error. I am on Window, building an x64 App, afaik in that case the MS Visual Studio linker is used instead of optilink. Will add your findings to the bug report.C++ Function: bool cppFunc( float[3] color ); D binding: extern(C++) bool cppFunc( float[3] color ); Using with: float[3] my_color; cppFunc( my_color ); -> Error: Internal Compiler Error: unable to pass staticarray to That part is a bug at least in the compiler message. Is it really an internal ctompiler error? Doesn't look like it: the compiler is talking to us happily. :) My simple test works for me: // 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 Builds and runs fine... on Linux... I don't know whether that's significant. Ali
Apr 28 2017
On Friday, 28 April 2017 at 18:07:49 UTC, ParticlePeter wrote:Interesting, your example corresponds to my third case, the linker error. I am on Window, building an x64 App, afaik in that case the MS Visual Studio linker is used instead of optilink. Will add your findings to the bug report.Apparently 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
Apr 28 2017
On Friday, 28 April 2017 at 18:41:22 UTC, kinke wrote:On Friday, 28 April 2017 at 18:07:49 UTC, ParticlePeter wrote:The worst part about that is mangling aside, the two declarations are identical to the compiler. AtilaInteresting, your example corresponds to my third case, the linker error. I am on Window, building an x64 App, afaik in that case the MS Visual Studio linker is used instead of optilink. Will add your findings to the bug report.Apparently 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
Apr 28 2017
On Saturday, 29 April 2017 at 01:49:56 UTC, Atila Neves wrote:On Friday, 28 April 2017 at 18:41:22 UTC, kinke wrote:In this context, can anybody explain [1], in particular, in this case, one should extern( C++ ) void cppSArray( ref float[3] color ); instead of: extern( C++ ) void cppSArray( float* color ); Others and me in this discussion seem to agree that parameter (float color[3]) is equivalent to (float* color) in C++ world. [1] http://dlang.org/spec/interfaceToC.html#passing_d_arrayOn Friday, 28 April 2017 at 18:07:49 UTC, ParticlePeter wrote:The worst part about that is mangling aside, the two declarations are identical to the compiler. AtilaInteresting, your example corresponds to my third case, the linker error. I am on Window, building an x64 App, afaik in that case the MS Visual Studio linker is used instead of optilink. Will add your findings to the bug report.Apparently 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
Apr 28 2017
On Saturday, 29 April 2017 at 06:22:03 UTC, ParticlePeter wrote:On Saturday, 29 April 2017 at 01:49:56 UTC, Atila Neves wrote:It's "just" the mangling. If it were `extern(C)` there'd be nothing to talk about. AtilaOn Friday, 28 April 2017 at 18:41:22 UTC, kinke wrote:In this context, can anybody explain [1], in particular, in this case, one should extern( C++ ) void cppSArray( ref float[3] color ); instead of: extern( C++ ) void cppSArray( float* color ); Others and me in this discussion seem to agree that parameter (float color[3]) is equivalent to (float* color) in C++ world. [1] http://dlang.org/spec/interfaceToC.html#passing_d_array[...]The worst part about that is mangling aside, the two declarations are identical to the compiler. Atila
Apr 29 2017
On Saturday, 29 April 2017 at 10:17:47 UTC, Atila Neves wrote:On Saturday, 29 April 2017 at 06:22:03 UTC, ParticlePeter wrote:O.k. got it, so both D variants work with the same C++ mangling, thanks.On Saturday, 29 April 2017 at 01:49:56 UTC, Atila Neves wrote:It's "just" the mangling. If it were `extern(C)` there'd be nothing to talk about. AtilaOn Friday, 28 April 2017 at 18:41:22 UTC, kinke wrote:In this context, can anybody explain [1], in particular, in this case, one should extern( C++ ) void cppSArray( ref float[3] color ); instead of: extern( C++ ) void cppSArray( float* color ); Others and me in this discussion seem to agree that parameter (float color[3]) is equivalent to (float* color) in C++ world. [1] http://dlang.org/spec/interfaceToC.html#passing_d_array[...]The worst part about that is mangling aside, the two declarations are identical to the compiler. Atila
Apr 29 2017
On Friday, 28 April 2017 at 17:57:34 UTC, Ali Çehreli wrote:On 04/28/2017 08:56 AM, ParticlePeter wrote:Btw, according to [1] your example should not work either, I doubt that there is a difference between C and C++ interfacing, it should be: extern(C++) float cppFunc( ref float[3] color ); In my case its a linker error as well. [1] http://dlang.org/spec/interfaceToC.html#passing_d_arrayC++ Function: bool cppFunc( float[3] color ); D binding: extern(C++) bool cppFunc( float[3] color ); Using with: float[3] my_color; cppFunc( my_color ); -> Error: Internal Compiler Error: unable to pass staticarray to That part is a bug at least in the compiler message. Is it really an internal ctompiler error? Doesn't look like it: the compiler is talking to us happily. :) My simple test works for me: // 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 Builds and runs fine... on Linux... I don't know whether that's significant. Ali
Apr 28 2017
On Friday, 28 April 2017 at 19:08:18 UTC, ParticlePeter wrote:On Friday, 28 April 2017 at 17:57:34 UTC, Ali Çehreli wrote:If you are having problems with the linker with Ali's you can do ``` extern(C++) bool cppFunc( float[3] color ); // correct signature, but causes compiler error pragma(mangle, cppFunc.mangleof) float cppFunc(float * color); // compatible signature but wrong mangling overridden with pragma(mangle,...)On 04/28/2017 08:56 AM, ParticlePeter wrote:Btw, according to [1] your example should not work either, I doubt that there is a difference between C and C++ interfacing, it should be: extern(C++) float cppFunc( ref float[3] color ); In my case its a linker error as well. [1] http://dlang.org/spec/interfaceToC.html#passing_d_arrayC++ Function: bool cppFunc( float[3] color ); D binding: extern(C++) bool cppFunc( float[3] color ); Using with: float[3] my_color; cppFunc( my_color ); -> Error: Internal Compiler Error: unable to pass staticarray to That part is a bug at least in the compiler message. Is it really an internal ctompiler error? Doesn't look like it: the compiler is talking to us happily. :) My simple test works for me: // 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 Builds and runs fine... on Linux... I don't know whether that's significant. Ali
Apr 28 2017
On Saturday, 29 April 2017 at 00:31:32 UTC, Nicholas Wilson wrote:If you are having problems with the linker with Ali's you can do ``` extern(C++) bool cppFunc( float[3] color ); // correct signature, but causes compiler error pragma(mangle, cppFunc.mangleof) float cppFunc(float * color); // compatible signature but wrong mangling overridden with pragma(mangle,...)Thanks for that hint! I got it to work. Side note, cppFunc.mangleof cannot be used as it is unknown. I guess your intention was to get the C++ mangling from somewhere else, I got it from dependency walker.
Apr 29 2017
On Saturday, 29 April 2017 at 08:08:27 UTC, ParticlePeter wrote:On Saturday, 29 April 2017 at 00:31:32 UTC, Nicholas Wilson wrote:But still, this needs to be fixed, copy pasting the name mangling is in my opinion just a hack for your specific cpp compiler on your specific platform.If you are having problems with the linker with Ali's you can do ``` extern(C++) bool cppFunc( float[3] color ); // correct signature, but causes compiler error pragma(mangle, cppFunc.mangleof) float cppFunc(float * color); // compatible signature but wrong mangling overridden with pragma(mangle,...)Thanks for that hint! I got it to work. Side note, cppFunc.mangleof cannot be used as it is unknown. I guess your intention was to get the C++ mangling from somewhere else, I got it from dependency walker.
Apr 29 2017
On Saturday, 29 April 2017 at 18:54:36 UTC, سليمان السهمي (Soulaïman Sahmi) wrote:But still, this needs to be fixed, copy pasting the name mangling is in my opinion just a hack for your specific cpp compiler on your specific platform.It can't be fixed on the D side as the Visual C++ mangling of `float color[3]` as `float * const color` cannot be represented in D, see the corresponding DMD issue https://issues.dlang.org/show_bug.cgi?id=17359. Just to be clear, a D declaration `extern(C++) bool cppFunc(float[3] color)` isn't compatible with the nearly identically looking C++ one, as it implies by-value semantics for `color` (not available in C++), that's why DMD doesn't allow it and so can't mangle it according to the target's C++ compiler. And the C++ byref version `float (&color)[3]` is mangled differently again (compatible with D's `ref float[3]`).
Apr 29 2017