result.m_type
mantielero opened this issue · comments
I am playing with OCCUtils. It depends on OpenCascade library.
I wrote the following example:
{.passL: "-loccutils".}
{.passC:"-I/usr/local/include/occutils -I/usr/include/opencascade" .}
import cinterop
# From: /usr/include/opencascade
type
TopoDS_Shape* {.importcpp: "TopoDS_Shape", header: "TopoDS_Shape.hxx", bycopy.} = object of RootObj
TopoDS_Solid* {.importcpp: "TopoDS_Solid", header: "TopoDS_Solid.hxx", bycopy.} = object of TopoDS_Shape
# From: /usr/local/include/occutils
csource "Primitive.hxx":
cnamespace OCCUtils:
cnamespace Primitive:
type primitive* {.cgen:"OCCUtils::Primitive::$1(@)".} = object of CClass # OCCUtils::Primitive::$1(@)
proc makeCube*(size:float):TopoDS_Solid =
cexpr[TopoDS_Solid]^primitive.MakeCube(size)
proc main() =
var myCube:TopoDS_Solid = makeCube(5)
main()
Which gives me the following error:
error: ‘class TopoDS_Solid’ has no member named ‘m_type’
89 | result.m_type = (&NTI__iFNg5Zv78nzJlY9cUWwvWwg_);
The c++ created contains:
...
/* section: NIM_merge_PROCS */
N_LIB_PRIVATE N_NIMCALL(TopoDS_Solid, makeCube__0MVTOneNhGZEGBJK1P9cGWQ)(NF size) {
TopoDS_Solid result;
result.m_type = (&NTI__iFNg5Zv78nzJlY9cUWwvWwg_); //<------ ERROR
result = /*OCCUtils::Primitive::primitive*/OCCUtils::Primitive::MakeCube(size);
return result;
}
...
As a side note, I have tried this {.cgen:"OCCUtils::Primitive::$1(@)".}
and {.cgen:"$1(@)".}. In the second case, shouldn't ÒCCUtils
and Primitive
be added given the cnamescape
? Or maybe cnamescape
shouldn't be used if I am using cgen
?
You don't really need the cnamespace
for this case. For your issue, try doing:
proc makeCube*(size:float):TopoDS_Solid {.noinit.} =
cexpr[TopoDS_Solid]^primitive.MakeCube(size)
The noinit
tells Nim not to initialize the hidden result
variable and just return it directly.
You might also want to avoid using RootObj
with interop stuff, as I've seen it cause problems before. You can either use CClass
or use the inheritable
pragma instead.
Note that cinterop
is not a replacement for header
+ importcpp
; it is meant to work alongside those pragmas. The point of the library is so you don't have to declare C++ types and functions to use them directly in your code. If you're going to declare functions on your own, it's better to just use importcpp
and header
directly:
proc makeCube*(size:float):TopoDS_Solid {.header:"Primitive.hxx" importcpp:"OCCUtils::Primitive::$1(@)".}
I added this in the readme a couple days ago:
This project is not a replacement for hand-written wrappers or wrapper generators like c2nim. This library is useful for quickly prototyping new code that depend on large C/C++ libraries, and is carefully designed so code can progressively be migrated to use Nim's
header
andimportcpp
pragmas directly.
Thanks a lot. It worked.
I am aware that this is no replacement for importcpp
, but it is helping me a lot to understand better what I need to do.