Jump to page: 1 2
Thread overview
C++ Interfacing:'static' array function parameter contradiction
Apr 28, 2017
ParticlePeter
Apr 28, 2017
Kagamin
Apr 28, 2017
kinke
Apr 28, 2017
ParticlePeter
Apr 28, 2017
Ali Çehreli
Apr 28, 2017
ParticlePeter
Apr 28, 2017
kinke
Apr 29, 2017
Atila Neves
Apr 29, 2017
ParticlePeter
Apr 29, 2017
Atila Neves
Apr 29, 2017
ParticlePeter
Apr 28, 2017
ParticlePeter
Apr 29, 2017
Nicholas Wilson
Apr 29, 2017
ParticlePeter
Apr 29, 2017
kinke
April 28, 2017
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?
April 28, 2017
Report a bug.
April 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 ]);
}
April 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:
>> 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 ]);
> }

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.
April 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 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

April 28, 2017
On Friday, 28 April 2017 at 17:57:34 UTC, Ali Çehreli wrote:
> 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 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

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.
April 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



April 28, 2017
On Friday, 28 April 2017 at 17:57:34 UTC, Ali Çehreli wrote:
> 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 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

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_array
April 29, 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:
>> 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 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
>
> 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_array

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,...)


April 29, 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:
>> 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

The worst part about that is mangling aside, the two declarations are identical to the compiler.

Atila
« First   ‹ Prev
1 2