Re: What is the wrong with my C++ interfacing
On Monday, 16 March 2020 at 09:28:15 UTC, drug wrote: On 3/16/20 12:24 PM, Ferhat Kurtulmuş wrote: Ok, here is a solution. I opened my lib (yielded by my auxilary cpp) using 7zip. There are two files containing symbol names, 1.txt and 2.txt. I searched for names of member functions. They were not there because c++ compiler does not compile member functions of class templates because we don't actually use them. So, I simply include this line in my aux cpp file and recompiled it: template class cv::Size_; I reopened 1.txt and they are there now: ?area@?$Size_@H@cv@@QEBAHXZ ?aspectRatio@?$Size_@H@cv@@QEBANXZ now everything works :D Would be nice if you update wiki ;) It would be better for someone more experienced to do this ;)
Re: What is the wrong with my C++ interfacing
On 3/16/20 12:24 PM, Ferhat Kurtulmuş wrote: Ok, here is a solution. I opened my lib (yielded by my auxilary cpp) using 7zip. There are two files containing symbol names, 1.txt and 2.txt. I searched for names of member functions. They were not there because c++ compiler does not compile member functions of class templates because we don't actually use them. So, I simply include this line in my aux cpp file and recompiled it: template class cv::Size_; I reopened 1.txt and they are there now: ?area@?$Size_@H@cv@@QEBAHXZ ?aspectRatio@?$Size_@H@cv@@QEBANXZ now everything works :D Would be nice if you update wiki ;)
Re: What is the wrong with my C++ interfacing
On Monday, 16 March 2020 at 07:46:00 UTC, drug wrote: On 3/16/20 10:11 AM, Ferhat Kurtulmuş wrote: On Sunday, 15 March 2020 at 22:25:27 UTC, Arine wrote: On Sunday, 15 March 2020 at 21:27:32 UTC, Ferhat Kurtulmuş extern(C++, cv){ extern(C++, class) struct Size_(_Tp){ @disable this(); ~this() { } final _Tp area() const; final double aspectRatio() const; final bool empty() const; _Tp width; //!< the width _Tp height; //!< the height } } extern(C++){ cv.Size_!int* createSizeIntWH(int w, int h); } void main() { Size_!int* sz = createSizeIntWH(200, 100); writeln(sz.width); } This worked for me too. But member functions are still causing linker error. It seems like docs (https://dlang.org/spec/cpp_interface.html) do not cover those situations. Is there any other sources to read for it. Maybe you make a pull request to docs covering C++ interfacing tips in detail. Not tested: extern(C++, class) struct Size_(_Tp){ @disable this(); ~this() { } extern(C++): // <- IIRC linkage should be set for members separately from aggregate final _Tp area() const; final double aspectRatio() const; final bool empty() const; _Tp width; //!< the width _Tp height; //!< the height } Ok, here is a solution. I opened my lib (yielded by my auxilary cpp) using 7zip. There are two files containing symbol names, 1.txt and 2.txt. I searched for names of member functions. They were not there because c++ compiler does not compile member functions of class templates because we don't actually use them. So, I simply include this line in my aux cpp file and recompiled it: template class cv::Size_; I reopened 1.txt and they are there now: ?area@?$Size_@H@cv@@QEBAHXZ ?aspectRatio@?$Size_@H@cv@@QEBANXZ now everything works :D
Re: What is the wrong with my C++ interfacing
On 3/16/20 10:11 AM, Ferhat Kurtulmuş wrote: On Sunday, 15 March 2020 at 22:25:27 UTC, Arine wrote: On Sunday, 15 March 2020 at 21:27:32 UTC, Ferhat Kurtulmuş extern(C++, cv){ extern(C++, class) struct Size_(_Tp){ @disable this(); ~this() { } final _Tp area() const; final double aspectRatio() const; final bool empty() const; _Tp width; //!< the width _Tp height; //!< the height } } extern(C++){ cv.Size_!int* createSizeIntWH(int w, int h); } void main() { Size_!int* sz = createSizeIntWH(200, 100); writeln(sz.width); } This worked for me too. But member functions are still causing linker error. It seems like docs (https://dlang.org/spec/cpp_interface.html) do not cover those situations. Is there any other sources to read for it. Maybe you make a pull request to docs covering C++ interfacing tips in detail. Not tested: extern(C++, class) struct Size_(_Tp){ @disable this(); ~this() { } extern(C++): // <- IIRC linkage should be set for members separately from aggregate final _Tp area() const; final double aspectRatio() const; final bool empty() const; _Tp width; //!< the width _Tp height; //!< the height }
Re: What is the wrong with my C++ interfacing
On Sunday, 15 March 2020 at 22:25:27 UTC, Arine wrote: On Sunday, 15 March 2020 at 21:27:32 UTC, Ferhat Kurtulmuş extern(C++, cv){ extern(C++, class) struct Size_(_Tp){ @disable this(); ~this() { } final _Tp area() const; final double aspectRatio() const; final bool empty() const; _Tp width; //!< the width _Tp height; //!< the height } } extern(C++){ cv.Size_!int* createSizeIntWH(int w, int h); } void main() { Size_!int* sz = createSizeIntWH(200, 100); writeln(sz.width); } This worked for me too. But member functions are still causing linker error. It seems like docs (https://dlang.org/spec/cpp_interface.html) do not cover those situations. Is there any other sources to read for it. Maybe you make a pull request to docs covering C++ interfacing tips in detail.
Re: What is the wrong with my C++ interfacing
On Sunday, 15 March 2020 at 21:27:32 UTC, Ferhat Kurtulmuş wrote: On Sunday, 15 March 2020 at 21:16:43 UTC, Arine wrote: On Sunday, 15 March 2020 at 20:53:49 UTC, Ferhat Kurtulmuş I wouldn't use a class on the D side, unless your C++ type uses virtual functions. Classes in D are different from structs, it is not the same as C++ where they are basically the same thing. I know their differences, classes are reference types and structs are value types in D. That's not the only difference. It's why your code doesn't work. I actually don't need this code. I've already wrapped many c code, but have no so much experience with interfacing C++ code. I am trying to understand capabilities of D in interfacing with C++ and its limits. I would like to know why I can interface a template-free class, but not a class template. You can, you just aren't representing the C++ code properly in D. You don't want class, it means something different in D than in C++. This works for me, as it is using struct that corresponds to the C++ type. You have to use extern(C++, class), as it is using "class" on the C++ side, which produces a different mangling. extern(C++, cv){ extern(C++, class) struct Size_(_Tp){ @disable this(); ~this() { } final _Tp area() const; final double aspectRatio() const; final bool empty() const; _Tp width; //!< the width _Tp height; //!< the height } } extern(C++){ cv.Size_!int* createSizeIntWH(int w, int h); } void main() { Size_!int* sz = createSizeIntWH(200, 100); writeln(sz.width); }
Re: What is the wrong with my C++ interfacing
On Sunday, 15 March 2020 at 21:16:43 UTC, Arine wrote: On Sunday, 15 March 2020 at 20:53:49 UTC, Ferhat Kurtulmuş I wouldn't use a class on the D side, unless your C++ type uses virtual functions. Classes in D are different from structs, it is not the same as C++ where they are basically the same thing. I know their differences, classes are reference types and structs are value types in D. I actually don't need this code. I've already wrapped many c code, but have no so much experience with interfacing C++ code. I am trying to understand capabilities of D in interfacing with C++ and its limits. I would like to know why I can interface a template-free class, but not a class template.
Re: What is the wrong with my C++ interfacing
On Sunday, 15 March 2020 at 20:53:49 UTC, Ferhat Kurtulmuş wrote: On Sunday, 15 March 2020 at 20:46:14 UTC, drug wrote: 15.03.2020 23:25, Ferhat Kurtulmuş пишет: On Sunday, 15 March 2020 at 20:21:57 UTC, drug wrote: 15.03.2020 22:39, Ferhat Kurtulmuş пишет: What is the D version of `createSizeIntWH`? In C++ it returns a pointer but in D version it returns an instance. extern(C++){ cv.Size_!int createSizeInt(); cv.Size_!int createSizeIntWH(int w, int h); void deleteSizeInt(ref cv.Size_!int sz); } createSizeIntWH returns a pointer to instance, not an instance. Try: cv.Size_!int* createSizeIntWH(int w, int h); I doubt it because in https://dlang.org/spec/cpp_interface.html#using_cpp_classes_from_d cpp code: Derived *createInstance(int i) d code: extern (C++){ ... Derived createInstance(int i); } I wouldn't use a class on the D side, unless your C++ type uses virtual functions. Classes in D are different from structs, it is not the same as C++ where they are basically the same thing.
Re: What is the wrong with my C++ interfacing
15.03.2020 23:53, Ferhat Kurtulmuş пишет: I doubt it because in https://dlang.org/spec/cpp_interface.html#using_cpp_classes_from_d cpp code: Derived *createInstance(int i) d code: extern (C++){ ... Derived createInstance(int i); } Ah, really, you use classes on D side.
Re: What is the wrong with my C++ interfacing
On Sunday, 15 March 2020 at 20:46:14 UTC, drug wrote: 15.03.2020 23:25, Ferhat Kurtulmuş пишет: On Sunday, 15 March 2020 at 20:21:57 UTC, drug wrote: 15.03.2020 22:39, Ferhat Kurtulmuş пишет: What is the D version of `createSizeIntWH`? In C++ it returns a pointer but in D version it returns an instance. extern(C++){ cv.Size_!int createSizeInt(); cv.Size_!int createSizeIntWH(int w, int h); void deleteSizeInt(ref cv.Size_!int sz); } createSizeIntWH returns a pointer to instance, not an instance. Try: cv.Size_!int* createSizeIntWH(int w, int h); I doubt it because in https://dlang.org/spec/cpp_interface.html#using_cpp_classes_from_d cpp code: Derived *createInstance(int i) d code: extern (C++){ ... Derived createInstance(int i); }
Re: What is the wrong with my C++ interfacing
15.03.2020 23:25, Ferhat Kurtulmuş пишет: On Sunday, 15 March 2020 at 20:21:57 UTC, drug wrote: 15.03.2020 22:39, Ferhat Kurtulmuş пишет: What is the D version of `createSizeIntWH`? In C++ it returns a pointer but in D version it returns an instance. extern(C++){ cv.Size_!int createSizeInt(); cv.Size_!int createSizeIntWH(int w, int h); void deleteSizeInt(ref cv.Size_!int sz); } createSizeIntWH returns a pointer to instance, not an instance. Try: cv.Size_!int* createSizeIntWH(int w, int h);
Re: What is the wrong with my C++ interfacing
On Sunday, 15 March 2020 at 20:21:57 UTC, drug wrote: 15.03.2020 22:39, Ferhat Kurtulmuş пишет: What is the D version of `createSizeIntWH`? In C++ it returns a pointer but in D version it returns an instance. extern(C++){ cv.Size_!int createSizeInt(); cv.Size_!int createSizeIntWH(int w, int h); void deleteSizeInt(ref cv.Size_!int sz); }
Re: What is the wrong with my C++ interfacing
15.03.2020 22:39, Ferhat Kurtulmuş пишет: The original C++ class https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/types.hpp#L315: template class Size_ { public: typedef _Tp value_type; //! default constructor Size_(); Size_(_Tp _width, _Tp _height); Size_(const Size_& sz); Size_(Size_&& sz) CV_NOEXCEPT; Size_(const Point_<_Tp>& pt); Size_& operator = (const Size_& sz); Size_& operator = (Size_&& sz) CV_NOEXCEPT; //! the area (width*height) _Tp area() const; //! aspect ratio (width/height) double aspectRatio() const; //! true if empty bool empty() const; //! conversion of another data type. template operator Size_<_Tp2>() const; _Tp width; //!< the width _Tp height; //!< the height }; // my auxiliary cpp code: cv::Size_* createSizeIntWH(int _width, int _height){ return new cv::Size_(_width, _height); } void deleteSizeInt(cv::Size_ *&sz){ delete sz; } // d code: extern(C++, cv){ class Size_(_Tp){ @disable this(); final _Tp area() const; final double aspectRatio() const; final bool empty() const; _Tp width; //!< the width _Tp height; //!< the height } } // my test code that fails: Size_!int sz = createSizeIntWH(200, 100); writeln(sz.width); What is the D version of `createSizeIntWH`? In C++ it returns a pointer but in D version it returns an instance. One of the problems is that sz.width is not printed as 200, but a random int. Other problem is that if I try to call one of area, aspectRatio, and empty, it does not compile yielding a linker error: error LNK2019: unresolved external symbol "public: int __cdecl cv::Size_::area(void)const " (?area@?$Size_@H@cv@@QEBAHXZ) referenced in function _Dmain Somehow linker cannot locate that symbol. Is this a name mangling issue? In the same library I could successfully interface cv::Mat which is a template-free definition. I suspect if D allows interfacing C++ class templates since docs do not cover this, but only struct templates?
What is the wrong with my C++ interfacing
The original C++ class https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/types.hpp#L315: template class Size_ { public: typedef _Tp value_type; //! default constructor Size_(); Size_(_Tp _width, _Tp _height); Size_(const Size_& sz); Size_(Size_&& sz) CV_NOEXCEPT; Size_(const Point_<_Tp>& pt); Size_& operator = (const Size_& sz); Size_& operator = (Size_&& sz) CV_NOEXCEPT; //! the area (width*height) _Tp area() const; //! aspect ratio (width/height) double aspectRatio() const; //! true if empty bool empty() const; //! conversion of another data type. template operator Size_<_Tp2>() const; _Tp width; //!< the width _Tp height; //!< the height }; // my auxiliary cpp code: cv::Size_* createSizeIntWH(int _width, int _height){ return new cv::Size_(_width, _height); } void deleteSizeInt(cv::Size_ *&sz){ delete sz; } // d code: extern(C++, cv){ class Size_(_Tp){ @disable this(); final _Tp area() const; final double aspectRatio() const; final bool empty() const; _Tp width; //!< the width _Tp height; //!< the height } } // my test code that fails: Size_!int sz = createSizeIntWH(200, 100); writeln(sz.width); One of the problems is that sz.width is not printed as 200, but a random int. Other problem is that if I try to call one of area, aspectRatio, and empty, it does not compile yielding a linker error: error LNK2019: unresolved external symbol "public: int __cdecl cv::Size_::area(void)const " (?area@?$Size_@H@cv@@QEBAHXZ) referenced in function _Dmain Somehow linker cannot locate that symbol. Is this a name mangling issue? In the same library I could successfully interface cv::Mat which is a template-free definition. I suspect if D allows interfacing C++ class templates since docs do not cover this, but only struct templates?