[vtkusers] c# port of VTK

Andy Somogyi endre-somogyi at comcast.net
Mon Aug 2 20:56:00 EDT 2004


Originally, I thought of creating a wrapper. I investigated both
managed c++ and c wrappers, but I determined that both approaches are
unacceptable.

1: managed c++ is EXTREMLY ugly and very non-portable, it is a windows only
solution.

2: A C wrapper is cross platform, and is a much better solution than managed
c++.

The problem with both approaches is virtuals, VTK has tons of them. In order to
create a proper .net binding, every single derived most class must be inherited
from (in c++ land), and every single virtual must be overriden to first check if
a c# class has overridden the virtual, and if so call the c# method, otherwise,
call the original c++ function.

As you can imagine, performance would be absolutly abysmal, as the c++ / c#
transition is VERY costly. Calling C functions from c# is cheap, it only takes
an extra 2 instructions over calling a standard c# function, but the other way
around, calling a c# function (it has be registered as a callback) from c or c++
is VERY expensive. Not to mention that the c# side of the wrapper would also be
extremly ugly, as a callback (event in c#) must be created for every single
virtual in c++, and this c# callback would then have to call a virtual on the c#
side.

Therefore, a 'wrapper' has been ruled out.

> I am not C# savvy, but are you saying that you cannot just pass a good 
> old array of 3 doubles? Whatever you pass in (array[3] or 3 doubles), 
> the point coordinates are *copied* into the internal instance of 
> vtkDataArray. There is no need to be allocating a new array[3] each time 
> you call SetPoint. For example, you could implement the first version of 
> SetPoint using the second:

Yes, you can pass an array of 3 doubles. c# can deal with 2 kinds of arrays,
managed and un-managed. Managed arrays are native .net types, they are syntacally
almost identical to c++ style arrays, except that they all have a 'Length' property
indicating the length of the array, so you would write code like:

for(int i = 0; i < myArray.Length; i++)
{
	myArray[i] = something;
}

Managed arrays are allways allocated on the garbage collected heap, and they also
contain an extra 12 bytes of data to store a garbage collection handle, run time
type info, length and so forth.

Unmanged arrays are simply pointers to a raw block or memory, they can be either
stack or heap allocated, but if heap allocated, must be cleaned up. If they are stack
allocated, they can be be kept around after the function finishes, other than by copying
its contents.

The big problem with unmanged arrays is that they are passed as a raw pointer (double*).
In c++, you can give some hints as the size of the array, such as :
void SetPoint(const double x[3])
Even though this is still passed as a pointer in c++, the array size x[3] is 'hinted' in the
function declaration.

Passing an unmanged array in c# looks like:
void SetPoint(double* x)
There is not even a hint that this is of length 3, therefore it is very error prone.

It is true that the SetPoint just coppies the values into a memory block, I'm more
concerned about getting values out, and not unnecessarily copying the values
over and over again.

> 
> void SetPoint(vtkIdType id, const double a[3])
>   { this->SetPoint(id, a[0], a[1], a[2]); }
> 
>> That is why I am considering changing the interface to use a Vector
> 
>  > struct instead of a managed array. A struct in c# is a value type, it
>  > is allways allocated on the stack, and has virtually no overhead. It
>  > behaves just like a good old C style struct.
> 
>>
>> So, using a Vector struct, the new method signatures would look like:
>> public void SetPoint(IdType id, Vector3 x) ;
>> public void SetPoint(IdType id, double x, double y, double z);
>>
>> The other advantage of useing a struct is that in time critical
> 
>  > sections, it can be cast as a double* and accessed just like a raw
>  > memory block.
> 
>>
>> The biggest disadvantage of using a Vector struct is that in
> 
>  > introduces an unfarmiliar syntax to current VTK users who are used to
>  > using a double x[3] array in c++.
> 
>>
> Well ... in the case that my assessment above is wrong *and* since you 
> are porting rather than wrapping VTK ... I suppose making API changes is 
> not out of the question. Just consider that the road that you are going 
> down is similar to that of the Mesa port of OpenGL. You may find that 
> this is more than a one man show. The point at which you port from C++ 
> will be a separate branch of development. This is what I mean by 
> difficult to maintain.
> 
> I think that you really should consider an automated wrapping approach.
>
> -Sean
> 
>>> Andy,
>>>
>>>   I am sure that a C# port could be very popular. Are you using a 
>>> wrapping approach or are you parsing C++ code to generate C#?
>>>
>>>   Also, I am unsure of where you are encountering the problem that 
>>> you describe in your message. Could you provide a few specific 
>>> instances?
>>>
>>> -Sean
>>>
>>> Andy Somogyi wrote:
>>>
>>>> Hello VTK users
>>>>
>>>> I am in the process of completly porting VTK (4.2) to c#.
>>>> As this is c#, it can be used nativly from any .net language.
>>>>
>>>> When finished, it will be freely availble under the existing VTL 
>>>> lisence.
>>>>
>>>> My question is this:
>>>>
>>>> The c++ version of VTK uses length 3 arrays to represent a vector in 
>>>> 3 space.
>>>> This is fine in c++ because you can create arrays on the stack.
>>>>
>>>> It is not possible to create a managed array in c# on the stack, 
>>>> they are allways
>>>> heap allocated and garbage collected. So using a large number of 
>>>> managed arrays, or
>>>> creating large numbers of transitory arrays is very inefficient.
>>>>
>>>> The use of a 'value type' or a 'struct' in other words is far more 
>>>> effcient when
>>>> large numbers of objects are involved as they are created on the 
>>>> stack and are not
>>>> garbage collected.
>>>>
>>>> I have thought about using a raw double pointer (double*) instead of 
>>>> an managed array
>>>> for all functions that use a vector (double[3]). This has the 
>>>> advantage of being very
>>>> fast, but on the other hand, it is highly error prone, and a user of 
>>>> one of these functions
>>>> must declare thier method 'unsafe'. I would suspsct that this would 
>>>> discourage many users.
>>>>
>>>> There are many good vector and matrix classes avaible for .net, such 
>>>> as the standard vector and
>>>> matrix types that ship with directx 9.
>>>>
>>>> So my question to any perspective vtk.net users is would you prefer 
>>>> all existing methods
>>>> that currently accept a c++ style array (double[3]) accept the 
>>>> following in the new
>>>> c# port:
>>>>
>>>> 1: managed array (new double[3])
>>>>    advantages:
>>>>    1.1 farmiliar syntax
>>>>    1.2 do not have to declare 'unsafe' code
>>>>    disadvanteges:
>>>>    1.2 very ineffcient both in terms of size and performance
>>>>
>>>> 2: unmanaged pointer (double*)
>>>>    advanteges:
>>>>    2.1 very effecient
>>>>    disadvantes:
>>>>    2.2 error prone
>>>>    2.3 need to pin a managed array or use 'stackalloc'
>>>>
>>>> 3: use a 'Vector3' value type
>>>>    advanteges
>>>>    3.1 very effcient
>>>>    3.2 very safe
>>>>    3.3 easy to convert to and from a 'double*'
>>>>    disadvantes:
>>>>    3.3 introduces unfarmiliair syntax
>>>>
>>>> Any ides or oppinions would be greatly appcieated
>>>>
>>>> thanks
>>>>
> 
> 




More information about the vtkusers mailing list