www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - C++ / Wrong function signature generated for reference parameter

reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
I have the following C++ function signature:

	uint _begin(Image& image, const InitParams* initParams)
and the following D code:
  class InitParams {
  }
  class B2D {
    uint _begin(ref Image image, InitParams initParams);
  }
But this compiles to the following signature which is not found by the linker:
public: virtual unsigned int __cdecl b2d::Context2D::_begin(class 
b2d::Image * &,class b2d::InitParams *)
I don't understand why "ref Image" translates to "Image * &" and not 
"Image &". How can I get the C++ reference function signature written 
down in D?
-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster
May 02 2018
parent reply Rubn <where is.this> writes:
On Wednesday, 2 May 2018 at 21:55:31 UTC, Robert M. Münch wrote:
 I have the following C++ function signature:

 	uint _begin(Image& image, const InitParams* initParams)
 and the following D code:
  class InitParams {
  }
  class B2D {
    uint _begin(ref Image image, InitParams initParams);
  }
 But this compiles to the following signature which is not found 
 by the linker:
 public: virtual unsigned int __cdecl 
 b2d::Context2D::_begin(class b2d::Image * &,class 
 b2d::InitParams *)
 I don't understand why "ref Image" translates to "Image * &" 
 and not "Image &". How can I get the C++ reference function 
 signature written down in D?
If "Image" is a class then all classes are based as pointers to their respective object. So passing a ref to a class is kind of redundant. You want to use a struct which isn't passed by pointer, but by value. Which will then give you the signature you want.
May 02 2018
next sibling parent =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2018-05-03 02:23:27 +0000, Rubn said:

 If "Image" is a class then all classes are based as pointers to their 
 respective object.
Hi, ok. Didn't remember that this is always the case.
 So passing a ref to a class is kind of redundant.
Yes, that's why I was confused.
 You want to use a struct which isn't passed by pointer, but by value. 
 Which will then give you the signature you want.
On the C++ side, Image is a class. Sometimes I need to use a pointer to it and sometimes a reference when using C++ side functions. So, how do I make it possible to have both variants available in D? If I use class I always get a pointer, if I use strucut I always get a reference. Do I define two interfaces in D one as class and one as struct with different names and than cast things on the D side? -- Robert M. Münch http://www.saphirion.com smarter | better | faster
May 02 2018
prev sibling parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2018-05-03 02:23:27 +0000, Rubn said:

 You want to use a struct which isn't passed by pointer, but by value. 
 Which will then give you the signature you want.
In addition to my other post, using struct won't give the correct signature. That's the signature I need: public: unsigned int __cdecl b2d::Context2D::_begin(class b2d::Image & __ptr64,class b2d::Context2D::InitParams const * __ptr64) __ptr64 And this is what D does when using a struct: public: unsigned int __cdecl b2d::Context2D::_begin(struct b2d::Image &,class b2d::InitParams const * const) Of course the linker can't resolve this. Not sure about the const part too, if this is correct on the D side... -- Robert M. Münch http://www.saphirion.com smarter | better | faster
May 03 2018
parent reply kinke <kinke libero.it> writes:
On Thursday, 3 May 2018 at 07:00:03 UTC, Robert M. Münch wrote:
 using struct won't give the correct signature
That's why there's `extern(C++, class) struct Image`, see https://dlang.org/spec/cpp_interface.html#classes.
 Not sure about the const part too, if this is correct on the D 
 side...
As const is transitive in D, mangling a const object reference as C++ `const T *const` is consistent, but also means that a `const T *` cannot be mapped directly to D via a class (but as `const(T)*` if T is a D struct).
May 03 2018
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2018-05-03 09:34:56 +0000, kinke said:

 That's why there's `extern(C++, class) struct Image`, see 
 https://dlang.org/spec/cpp_interface.html#classes.
Hi, thanks. I didn't understand the docs as without any code examples for all the different cases, it's hard to derive the syntax and how to use it if one just gets started with this interface.
 As const is transitive in D, mangling a const object reference as C++ 
 `const T *const` is consistent, but also means that a `const T *` 
 cannot be mapped directly to D via a class (but as `const(T)*` if T is 
 a D struct).
Not sure I understand this too. This is now what I get: DMD: public: unsigned int __cdecl b2d::Context2D::_begin(class b2d::Image & __ptr64,class b2d::Context2D::InitParams const * __ptr64 const) __ptr64 LIB: public: unsigned int __cdecl b2d::Context2D::_begin(class b2d::Image & __ptr64,class b2d::Context2D::InitParams const * __ptr64) __ptr64 So I somehow get some more const from D. This is the code I used: final uint _begin(ref Image image, const(InitParams) initParams); Any idea how to solve this? I really like that I'm able to use C++ stuff from D but interfacing the tow is a bit tedious... it would be great to be able to write the C++ signature in the extern(C++) scope and have it translated to the D equivalent internally. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
May 03 2018
parent Timoses <timosesu gmail.com> writes:
On Thursday, 3 May 2018 at 11:29:59 UTC, Robert M. Münch wrote:
 Not sure I understand this too. This is now what I get:

 DMD: public: unsigned int __cdecl b2d::Context2D::_begin(class 
 b2d::Image & __ptr64,class b2d::Context2D::InitParams const * 
 __ptr64 const) __ptr64
 LIB: public: unsigned int __cdecl b2d::Context2D::_begin(class 
 b2d::Image & __ptr64,class b2d::Context2D::InitParams const * 
 __ptr64) __ptr64

 So I somehow get some more const from D. This is the code I 
 used:

    final uint _begin(ref Image image, const(InitParams) 
 initParams);

 Any idea how to solve this?

 I really like that I'm able to use C++ stuff from D but 
 interfacing the tow is a bit tedious... it would be great to be 
 able to write the C++ signature in the extern(C++) scope and 
 have it translated to the D equivalent internally.
Just as a note: Related (if not to say duplicate) topic: https://forum.dlang.org/post/pch39e$nt7$1 digitalmars.com
May 04 2018