n0bra1n3r / cinterop

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

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Question] Working with templates

mantielero opened this issue · comments

How should I work with templates?

I am trying to do this, but using your library.

The type Handle_Geom_TrimmedCurve is defined here:

Handle_Geom_TrimmedCurve* {.header: "Geom_TrimmedCurve.hxx", importcpp: "Handle_Geom_TrimmedCurve".} = Handle[Geom_TrimmedCurve]

and Handle is defined here.

So how would I do that with cinterop?

What I am trying to do is here but I get an error about init.

I'm interested in the error you're getting. This usecase should work, although I don't have a test with with a importcppd type alias like yours. Everything is just header and importcpp pragmas under the hood, and there's nothing special about my init implementation (though the Nim C++ codegen has some bugs you might be hitting):

proc init*[T: CClass](Class: type[T]): T
  {.importcpp:"'*1(@)" varargs constructor.}

I can give you a similar example with templates that works in my codebase:

# diligent.nim

cnamespace Diligent: # C++ namespace
  csource &"{GraphicsTools}/MapHelper.hpp": # `GraphicsTools` is something like 'src/externals/DiligentEngine/DiligentTools/include'
    type MapHelper*[T] = object of CClass
# renderer.nim

...
var lightAttrs = MapHelper[LightAttribs].init(
    self.immediateContextRef,
    self.lightAttrBufferRef,
    cauto^MAP_TYPE.WRITE,
    cauto^MAP_FLAGS.DISCARD)
...

If you're getting weird errors that have cpp or obj files in them, it might be useful to look at the generated code in your nimcache folder.

I compile my project with the switch --nimcache:nimcache so the generated C++ is right inside my project folder and I can easily take a look at the code.

I have the following code:

import occt

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


#let aArcOfCircle = GC_MakeArcOfCircle.init()
let aArcOfCircle:Handle_Geom_TrimmedCurve = GC_MakeArcOfCircle.init(aPnt2,aPnt3,aPnt4)

and the last line is giving me the error:

Error: attempting to call undeclared routine: 'init'

The way in which I am defining GC_MakeArcOfCircle and Handle_Geom_Trimmed_Curve:

# Wrapping code
const libPath = "/usr/include/opencascade"

import cinterop
import std/os


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


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

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

type
  Handle_Geom_TrimmedCurve* = handle[Geom_TrimmedCurve]

Where the headers look like this: GC_MakeArcOfCircle.hxx and Standard_Handle.hxx.

I think it was an stupid error. In order to have init available I need to import cinterop.

I still have an issue, so I will close this issue an open a new one.