www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Interfacing with C++ Class named Object

reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
parent reply Timoses <timosesu gmail.com> writes:
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
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
parent =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
May 01 2018