Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 15, 2020 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<typename _Tp> 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<typename _Tp2> operator Size_<_Tp2>() const; _Tp width; //!< the width _Tp height; //!< the height }; // my auxiliary cpp code: cv::Size_<int>* createSizeIntWH(int _width, int _height){ return new cv::Size_<int>(_width, _height); } void deleteSizeInt(cv::Size_<int> *&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_<int>::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? |
March 15, 2020 Re: What is the wrong with my C++ interfacing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ferhat Kurtulmuş | 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<typename _Tp> 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<typename _Tp2> operator Size_<_Tp2>() const; > > _Tp width; //!< the width > _Tp height; //!< the height > }; > > // my auxiliary cpp code: > cv::Size_<int>* createSizeIntWH(int _width, int _height){ > return new cv::Size_<int>(_width, _height); > } > > void deleteSizeInt(cv::Size_<int> *&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_<int>::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? > |
March 15, 2020 Re: What is the wrong with my C++ interfacing | ||||
---|---|---|---|---|
| ||||
Posted in reply to drug | 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); } |
March 15, 2020 Re: What is the wrong with my C++ interfacing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ferhat Kurtulmuş | 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);
|
March 15, 2020 Re: What is the wrong with my C++ interfacing | ||||
---|---|---|---|---|
| ||||
Posted in reply to drug | 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); } |
March 16, 2020 Re: What is the wrong with my C++ interfacing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ferhat Kurtulmuş | 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.
|
March 15, 2020 Re: What is the wrong with my C++ interfacing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ferhat Kurtulmuş | 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.
|
March 15, 2020 Re: What is the wrong with my C++ interfacing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arine | 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. |
March 15, 2020 Re: What is the wrong with my C++ interfacing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ferhat Kurtulmuş | 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); } |
March 16, 2020 Re: What is the wrong with my C++ interfacing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arine | 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. |
Copyright © 1999-2021 by the D Language Foundation