Thread overview
Interfacing with C++ Class named Object
May 01, 2018
Robert M. Münch
May 01, 2018
Timoses
May 01, 2018
Robert M. Münch
May 01, 2018
Robert M. Münch
May 01, 2018
Hi, I'm mostly doing simple C-API wrappers around C++ code to access thigns from D. However, I wanted to try how far I can come using C++ directly.

I have the following C++ code in namespace N:

class Image : public Object {
	Error create(int w, int h, uint32_t p) noexcept;
}
And I have the following D code:
extern (C++, N) {
 class Object {
 }
 class Image : public Object {
   uint create(int w, int h, uint pixelFormat);
 }
}
So frist problem I see is, that a C++ class names Object is pretty unfortunate as this is a reserved class name in D. And DMD doesn't seem to allow using Object inside a C++ scope (which IMO should be possible).
Am I right, that there is no chance to handle this case other than ranming the C++ base class?

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

May 01, 2018
On Tuesday, 1 May 2018 at 15:24:09 UTC, Robert M. Münch wrote:
> Hi, I'm mostly doing simple C-API wrappers around C++ code to access thigns from D. However, I wanted to try how far I can come using C++ directly.
>
> I have the following C++ code in namespace N:
>
> class Image : public Object {
> 	Error create(int w, int h, uint32_t p) noexcept;
> }
> And I have the following D code:
> extern (C++, N) {
>  class Object {
>  }
>  class Image : public Object {
>    uint create(int w, int h, uint pixelFormat);
>  }
> }
> So frist problem I see is, that a C++ class names Object is pretty unfortunate as this is a reserved class name in D. And DMD doesn't seem to allow using Object inside a C++ scope (which IMO should be possible).
> Am I right, that there is no chance to handle this case other than ranming the C++ base class?

Would `pragma(mangle, ...)` work here?
https://dlang.org/spec/pragma.html#mangle
May 01, 2018
On 2018-05-01 16:07:30 +0000, Timoses said:

> On Tuesday, 1 May 2018 at 15:24:09 UTC, Robert M. Münch wrote:
>> Hi, I'm mostly doing simple C-API wrappers around C++ code to access thigns from D. However, I wanted to try how far I can come using C++ directly.
>> 
>> I have the following C++ code in namespace N:
>> 
>> class Image : public Object {
>> 	Error create(int w, int h, uint32_t p) noexcept;
>> }
>> And I have the following D code:
>> extern (C++, N) {
>> class Object {
>> }
>> class Image : public Object {
>> uint create(int w, int h, uint pixelFormat);
>> }
>> }
>> So frist problem I see is, that a C++ class names Object is pretty unfortunate as this is a reserved class name in D. And DMD doesn't seem to allow using Object inside a C++ scope (which IMO should be possible).
>> Am I right, that there is no chance to handle this case other than ranming the C++ base class?
> 
> Would `pragma(mangle, ...)` work here?
> https://dlang.org/spec/pragma.html#mangle

Yes, great! Thanks. I could extend the code now. But I get a next problem:

extern (C++, b2d) {
 class AnyBase {
   bool isShared();
 }

 pragma(mangle, "Object");
 class b2dObject : AnyBase {
 }

 class Image : b2dObject {
 // class Image {
   uint create(int w, int h, uint pixelFormat);
 }
}

The linke complains about missing symbols:

error LNK2001: "public: virtual bool __cdecl b2d::AnyBase::isShared(void)" (?isShared@AnyBase@b2d@@UEBA_NXZ)
error LNK2001: "public: virtual unsigned int __cdecl b2d::Image::create(int,int,unsigned int)" (?create@Image@b2d@@UEAAIHHI@Z)

I have in my C++ link lib:

?isShared@AnyBase@b2d@@QEBA_NXZ which demangles to => public: BOOL __cdecl b2d::AnyBase::isShared(void)const __ptr64

So, the difference is the "virtual" specifier on the D side, while the C++ mangeling is missing this. I have this for many functions.

Any idea how to handle this?

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

May 01, 2018
On 2018-05-01 17:14:53 +0000, Robert M. Münch said:

> Yes, great! Thanks. I could extend the code now. But I get a next problem:
> 
> extern (C++, b2d) {
>   class AnyBase {
>     bool isShared();
>   }
> 
>   pragma(mangle, "Object");
>   class b2dObject : AnyBase {
>   }
> 
>   class Image : b2dObject {
>   // class Image {
>     uint create(int w, int h, uint pixelFormat);
>   }
> }
> 
> The linke complains about missing symbols:
> 
> error LNK2001: "public: virtual bool __cdecl b2d::AnyBase::isShared(void)" (?isShared@AnyBase@b2d@@UEBA_NXZ)
> error LNK2001: "public: virtual unsigned int __cdecl b2d::Image::create(int,int,unsigned int)" (?create@Image@b2d@@UEAAIHHI@Z)
> 
> I have in my C++ link lib:
> 
> ?isShared@AnyBase@b2d@@QEBA_NXZ which demangles to => public: BOOL __cdecl b2d::AnyBase::isShared(void)const __ptr64
> 
> So, the difference is the "virtual" specifier on the D side, while the C++ mangeling is missing this. I have this for many functions.
> 
> Any idea how to handle this?

Answering myself. There is a final keyword missing:

 class Image : b2dObject {
 // class Image {
   final uint create(int w, int h, uint pixelFormat);
 }

With this it's working.

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster