n0bra1n3r / cinterop

A C/C++ interop library for the Nim programming language

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Question] How to do deal with operators

mantielero opened this issue · comments

How should I deal with operators?

For instance, the following operator:

class GC_MakeArcOfCircle  : public GC_Root {
...
operator const Handle(Geom_TrimmedCurve)& () const { return Value(); }
...
}

gets wrapped by c2nim as something like:

converter `constopencascade`*(this: GC_MakeArcOfCircle): handle[Geom_TrimmedCurve] {.
    noSideEffect, importcpp: "GC_MakeArcOfCircle::operator constopencascade",
    header: "GC_MakeArcOfCircle.hxx".}

How would I use operators from cinterop.

My C++ is rusty, but this operator is an implicit conversion operator right?

So cinterop works at the syntax level, you don't need to actually match any types as long as the semantics of the C++ code is satisfied.

For this case, you probably don't need cinterop at all. You can use cinterop/decls to make it more convenient, but I think you just need the header and importcpp pragmas. Not sure what the definition of Handle is, but you can do implicit conversion with converters in Nim. The following is probably not the exact translation of what you want, but it might get you close:

csource "path/to/header.h":
  type GC_MakeArcOfCircle* = object of CClass
  type Geom_TrimmedCurve* = object of CClass

  converter toGeom_TrimmedCurve*(self: GC_MakeArcOfCircle): var Geom_TrimmedCurve
    {.importcpp:"(#)".}

Then you use it like this:

var test1 = GC_MakeArcOfCircle.init()
var test2: Geom_TrimmedCurve = test1 # implicit conversion happens here at both the Nim and C++ levels

if you want a C++ reference variable, you might need something like cref from cinterop/exprs:

let test2 {.cref.}: Geom_TrimmedCurve = test1

but currently cinterop does not support mutation of C++ reference variables due to a limitation in Nim's pragmas (related RFC).

No success yet. I have the following code:

  • bottle.nim:
import occt
import cinterop
let
  myWidth = 50.0
  myThickness = 20.0
  myHeight = 70.0
  aPnt1 = newPnt(-myWidth / 2.0, 0, 0)
  aPnt2 = newPnt(-myWidth / 2.0, -myThickness / 4.0, 0)
  aPnt3 = newPnt(0, -myThickness / 2.0, 0)
  aPnt4 = newPnt(myWidth / 2.0, -myThickness / 4.0, 0)
  aPnt5 = newPnt(myWidth / 2.0, 0, 0)

echo aPnt2
echo aPnt3
echo aPnt4

var aArcOfCircle  = makeArcOfCircle(aPnt2, aPnt3, aPnt4)  
  • gc.nim:
import cinterop
import gp_Pnt


csource "Standard_Handle.hxx":
  cnamespace opencascade:
    type
      handle*[T] = object of CClass

type
  Handle = handle

csource "Geom_TrimmedCurve.hxx":
  type
    Geom_TrimmedCurve* = object of CClass

type
  Handle_Geom_TrimmedCurve* = Handle[Geom_TrimmedCurve]

csource "GC_MakeArcOfCircle.hxx":
  type 
    GC_MakeArcOfCircle* = object of CClass
    gp_Circ* = object of CClass

  converter toHandle_Geom_TrimmedCurve*(self: GC_MakeArcOfCircle): var Handle_Geom_TrimmedCurve {.importcpp:"(#)".}
    

proc makeArcOfCircle*(a,b,c:Pnt):GC_MakeArcOfCircle =#Handle_Geom_TrimmedCurve =
  return GC_MakeArcOfCircle.init(a,b,c)

An error is raised on the generated c++ code:

/home/jose/.cache/nim/bottle_d/@mbottle.nim.cpp:103:34: error: no matching function for call to ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle()’
  103 | N_LIB_PRIVATE GC_MakeArcOfCircle aArcOfCircle__Uweq2PxKseJhRoJApFwnOw;
      |                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
En el fichero incluido desde /home/jose/.cache/nim/bottle_d/@mbottle.nim.cpp:14:
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:84:19: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(const gp_Pnt&, const gp_Vec&, const gp_Pnt&)’
   84 |   Standard_EXPORT GC_MakeArcOfCircle(const gp_Pnt& P1, const gp_Vec& V, const gp_Pnt& P2);
      |                   ^~~~~~~~~~~~~~~~~~
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:84:19: nota:   el candidato espera 3 argumentos, se proporcionaron 0
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:62:19: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(const gp_Pnt&, const gp_Pnt&, const gp_Pnt&)’
   62 |   Standard_EXPORT GC_MakeArcOfCircle(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3);
      |                   ^~~~~~~~~~~~~~~~~~
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:62:19: nota:   el candidato espera 3 argumentos, se proporcionaron 0
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:58:19: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(const gp_Circ&, const gp_Pnt&, const gp_Pnt&, Standard_Boolean)’
   58 |   Standard_EXPORT GC_MakeArcOfCircle(const gp_Circ& Circ, const gp_Pnt& P1, const gp_Pnt& P2, const Standard_Boolean Sense);
      |                   ^~~~~~~~~~~~~~~~~~
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:58:19: nota:   el candidato espera 4 argumentos, se proporcionaron 0
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:54:19: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(const gp_Circ&, const gp_Pnt&, Standard_Real, Standard_Boolean)’
   54 |   Standard_EXPORT GC_MakeArcOfCircle(const gp_Circ& Circ, const gp_Pnt& P, const Standard_Real Alpha, const Standard_Boolean Sense);
      |                   ^~~~~~~~~~~~~~~~~~
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:54:19: nota:   el candidato espera 4 argumentos, se proporcionaron 0
En el fichero incluido desde /home/jose/.cache/nim/bottle_d/@mbottle.nim.cpp:14:
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:49:19: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(const gp_Circ&, Standard_Real, Standard_Real, Standard_Boolean)’
   49 |   Standard_EXPORT GC_MakeArcOfCircle(const gp_Circ& Circ, const Standard_Real Alpha1, const Standard_Real Alpha2, const Standard_Boolean Sense);
      |                   ^~~~~~~~~~~~~~~~~~
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:49:19: nota:   el candidato espera 4 argumentos, se proporcionaron 0
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:39:7: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(const GC_MakeArcOfCircle&)’
   39 | class GC_MakeArcOfCircle  : public GC_Root
      |       ^~~~~~~~~~~~~~~~~~
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:39:7: nota:   el candidato espera 1 argumento, se proporcionaron 0
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:39:7: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(GC_MakeArcOfCircle&&)’
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:39:7: nota:   el candidato espera 1 argumento, se proporcionaron 0
/home/jose/.cache/nim/bottle_d/@mgc.nim.cpp: En la función ‘GC_MakeArcOfCircle makeArcOfCircle__IyOEPhf5t8KHn5UprzMDPQ(gp_Pnt*, gp_Pnt*, gp_Pnt*)’:
/home/jose/.cache/nim/bottle_d/@mgc.nim.cpp:98:28: error: no matching function for call to ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle()’
   98 |         GC_MakeArcOfCircle result;
      |                            ^~~~~~
En el fichero incluido desde /home/jose/.cache/nim/bottle_d/@mgc.nim.cpp:12:
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:84:19: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(const gp_Pnt&, const gp_Vec&, const gp_Pnt&)’
   84 |   Standard_EXPORT GC_MakeArcOfCircle(const gp_Pnt& P1, const gp_Vec& V, const gp_Pnt& P2);
      |                   ^~~~~~~~~~~~~~~~~~
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:84:19: nota:   el candidato espera 3 argumentos, se proporcionaron 0
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:62:19: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(const gp_Pnt&, const gp_Pnt&, const gp_Pnt&)’
   62 |   Standard_EXPORT GC_MakeArcOfCircle(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3);
      |                   ^~~~~~~~~~~~~~~~~~
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:62:19: nota:   el candidato espera 3 argumentos, se proporcionaron 0
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:58:19: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(const gp_Circ&, const gp_Pnt&, const gp_Pnt&, Standard_Boolean)’
   58 |   Standard_EXPORT GC_MakeArcOfCircle(const gp_Circ& Circ, const gp_Pnt& P1, const gp_Pnt& P2, const Standard_Boolean Sense);
      |                   ^~~~~~~~~~~~~~~~~~
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:58:19: nota:   el candidato espera 4 argumentos, se proporcionaron 0
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:54:19: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(const gp_Circ&, const gp_Pnt&, Standard_Real, Standard_Boolean)’
   54 |   Standard_EXPORT GC_MakeArcOfCircle(const gp_Circ& Circ, const gp_Pnt& P, const Standard_Real Alpha, const Standard_Boolean Sense);
      |                   ^~~~~~~~~~~~~~~~~~
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:54:19: nota:   el candidato espera 4 argumentos, se proporcionaron 0
En el fichero incluido desde /home/jose/.cache/nim/bottle_d/@mgc.nim.cpp:12:
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:49:19: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(const gp_Circ&, Standard_Real, Standard_Real, Standard_Boolean)’
   49 |   Standard_EXPORT GC_MakeArcOfCircle(const gp_Circ& Circ, const Standard_Real Alpha1, const Standard_Real Alpha2, const Standard_Boolean Sense);
      |                   ^~~~~~~~~~~~~~~~~~
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:49:19: nota:   el candidato espera 4 argumentos, se proporcionaron 0
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:39:7: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(const GC_MakeArcOfCircle&)’
   39 | class GC_MakeArcOfCircle  : public GC_Root
      |       ^~~~~~~~~~~~~~~~~~
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:39:7: nota:   el candidato espera 1 argumento, se proporcionaron 0
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:39:7: nota: candidate: ‘GC_MakeArcOfCircle::GC_MakeArcOfCircle(GC_MakeArcOfCircle&&)’
/usr/include/opencascade/GC_MakeArcOfCircle.hxx:39:7: nota:   el candidato espera 1 argumento, se proporcionaron 0
Error: execution of an external compiler program 'g++ -c -std=gnu++14 -funsigned-char  -w -fmax-errors=3 -fpermissive -I/usr/include/opencascade   -I/home/jose/.choosenim/toolchains/nim-1.4.8/lib -I/home/jose/src/occt.nim/src/lib -o /home/jose/.cache/nim/bottle_d/@mgc.nim.cpp.o /home/jose/.cache/nim/bottle_d/@mgc.nim.cpp' failed with exit code: 1

Where the cpp code is complaining about is:

  • @mgc.nim.cpp:
N_LIB_PRIVATE N_NIMCALL(GC_MakeArcOfCircle, makeArcOfCircle__IyOEPhf5t8KHn5UprzMDPQ)(gp_Pnt* a, gp_Pnt* b, gp_Pnt* c) {
	GC_MakeArcOfCircle result; //<--------- BLAMING LINE
	nimfr_("makeArcOfCircle", "/home/jose/src/occt.nim/src/lib/gc.nim");
{	nimln_(29, "/home/jose/src/occt.nim/src/lib/gc.nim");
	result = GC_MakeArcOfCircle((*a), (*b), (*c));
	goto BeforeRet_;
	}BeforeRet_: ;
	popFrame();
	return result;
}
  • @mbottle.nim.cpp:
/* section: NIM_merge_VARS */
N_LIB_PRIVATE NIM_CONST NF myWidth__4Dx1Z09bA3pua5C9aa1tzO9bg = 5.0000000000000000e+01;
N_LIB_PRIVATE NIM_CONST NF myThickness__jgfYRYDsoA1aSux3WNwLfA = 2.0000000000000000e+01;
N_LIB_PRIVATE NIM_CONST NF myHeight__9cE6D4OW0Dv9cPNqcUOfsMsQ = 7.0000000000000000e+01;
N_LIB_PRIVATE gp_Pnt aPnt1__6nbm5xlJ7PvXUKoJssDDjQ;
N_LIB_PRIVATE gp_Pnt aPnt2__Kk2fL5Mpd9cYsMZ47DXOCuQ;
N_LIB_PRIVATE gp_Pnt aPnt3__9czGtnL4XruNd3ShGqu9bjRQ;
N_LIB_PRIVATE gp_Pnt aPnt4__nocn09bSjOm249b6Cy9afk8kQ;
N_LIB_PRIVATE gp_Pnt aPnt5__kgutqiL8dpxwZe10yFf3Iw;
N_LIB_PRIVATE GC_MakeArcOfCircle aArcOfCircle__Uweq2PxKseJhRoJApFwnOw;  //<----- BLAMING LINE
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;
extern TFrame* framePtr__HRfVMH3jYeBJz6Q6X9b6Ptw;

I am a bit lost

It worked with a couple of changes:

csource "GC_MakeArcOfCircle.hxx":
  type 
    GC_MakeArcOfCircle* = object of CClass
    gp_Circ* = object of CClass

  converter toHandle_Geom_TrimmedCurve*(self: GC_MakeArcOfCircle):Handle_Geom_TrimmedCurve {.importcpp:"(#)".}
    

proc makeArcOfCircle*(a,b,c:Pnt):Handle_Geom_TrimmedCurve =
  return GC_MakeArcOfCircle.init(a,b,c)