Porting to NET : suggestions

Hello,

I think that there's a relatively quick way to port OpenCascade to .NET without using the SLOW PInvoke (or IJW), using Visual C++ 2005. Imagine having OpenCascade just compiled to CLR. Anyway it would be well usable only using C++/CLI (exactly like the native one), but usable at a decent level using C# and VB. The problem is that C# is unable to use Value classes (which OCC uses).

I saw the good "Wrapper" to C# , and the Syntax looks nice. Anyway:
- It requires 3 levels of indirection, plus additional memory for each used object.
- It is slow (anyway it won't be really noticeable 'cause OCC functions are more relevant)
- You could not port existing C++ code.

I just did some preliminar investigations:
- Handle classes and functions could be converted/used without problems in C# too. Handles could map exactly CLI Handles (^)
- In c++ you could use Exactly the same code( unless you use direct pointers)
- In C# you would use the same code with Handles , but non-handles functions require a different syntax. For example

C++
TopoDS_Shape A = GetMyTopoDsShape(10);
--
C#
TopoDS_Shape A = new TopoDS_Shape();
GetMyTopoDsShape(ref A,10);
(is really annoying!)

- You won't be able to use namespaces since you don't modify (almost) the source code.

---------
The steps should be the following:
- Port the System classes to .NET (not too Hard), just Wrap to NET types. Note: C++ types and CRT are automatically wrapped!
- substitute each "class" with "ref class" with the help of a preprocessor
- Make sure that each Class has a default constructor (even empty)and a copyconstructor (otherwise you won't compile). Maybe that's be biggest problem.
- Recompile the whole thing with the /clr option
- Tune some native high-performance requirements (like OpenGl).

At least for non visual classes it should work! Native things (OpenGL) will suffer of the native/wrapped transition. Anyway, they ported DirectX...

You can the use OCC functions natively without a wrapper from VB.NET , C#, C++/CLI

What about that?

Thomas

Jonathan Hill's picture

Hi Thomas,

You can download an example Visual Studio 2005 (.NET Framework v2.0) project I have created from: -
http://www.myxyz.co.uk/Downloads/Development/

(the path is case sensitive and it contains about 20Mb of files)

Its a simple Windows form hosting a OpenCASCADE window with a rotating sphere created on a thread.
(The debug folder also contains all the runtime .dll files, including the OpenCASCADE v5.2 runtime files)

I am currently working on support for the new OpenCASCADE v6.1.0 release.

Let me know if you have any comments or queries.

Jonathan

QbProg's picture

Hello,
thanks for the pointing , the example is nice! Anyway it is still a wrapper around the native version. I was thinking (just thinking) to compile the whole thing into .NET using C++/CLI. It would be faster and consume less memory.

What do you think about that?

P Dolbey's picture

How would it be faster? And how would it consume less memory?

Pete

QbProg's picture

Hello,

the fact is that existing wrappers are just ... wrappers! For each OpenCascade unmanaged class, a new one should be created. The new one wraps method by method the existing OCC functionality. For each instance of a class two instances need to be created (i.e one managed and one unmanaged).
For each managed call there must be a transition managed/unmanaged/managed which is (REALLY) slow. Progress has been made with IJW in VS2005, but the slowdown becomes important when you do many function calls (i.e. event handling).
--
Visual C++ 2005 simplifies the whole thing, and make "possible" to compile DIRECTLY OCC in .NET . I don't say simple, because it will require some work.
In .NET you can compile existing C++ code and classes directly to IL. Anyway it will generate "Native" classes (note: native is not unmanaged). These are compiled into .NET intermediate language, but are not accessible from C# or VB but only from C++. At this step you don't need anymore the managed/unmanaged transition and the wrappers.

ANYWAY,C# support is important. If you substitute each "class" with "ref class" you are then able to access these classes from everywhere (C# , VB). This approach works because OCC uses "Handles" and not Pointers. We could substitute the OCC Handle with the .NET handle ^. There are some problems:
- OCC "Standard" classes need some modifications.
- You can not use VALUE classes in C#. You are only allowed to use Handle(..) classes. (i.e. Handle(Geom_Point) but not gp_Pnt . This is not good because it makes the syntax more complex.
- References, when needed, have a different syntax.
- Each class should have a default copy constructor and a default constructor defined.

I'm trying to find a workaround for these problems.You can anyway access OCC from managed c++(/CLI) without modifications (as it was unmanaged) and port your existing code to the new platform with minor performance issues.

I'm just experimenting, so suggestions would be usefoul!
(sorry for my English)
Thomas

Gerhard Hofmann's picture

Hello Thomas and everyone,
As Thomas writes, wrappers are slow and consume memory. This is correct. And I would be very interested if anyone could solve the task that Thomas proposes. To me it seems too difficult and error prone. I preferred to keep OpenCascade code untouched and generate the wrapper as you can see in this thread: http://www.opencascade.org/org/forum/thread_8927/
You can download my approach at www.sofa.de and follow the "CADability" link to the download page. You will get (among all the other stuff) two dlls, "OpenCascade6.1.dll" and "OCasToDotNet.dll". The first one is a C# dll that you can reference, the second one is the C++ access to the OpenCascade objects. There is also an xml file which turns the cdl documentation into .NET intellisense but it is not included in that download. I could mail it to anyone interested. Let me know
Gerhard
(development at sofa.de)