Python access keywords for using compiled .NET method

Hi,

I have a method like this in c#

bool method(ref double[] values){
values = new double{0,1,2}
}

that I call in C# like this

double[] v;
method(v);

I see a lot of methods in RhinoCommon like curve closest points that returns values by referece.

How do you get output from such function in Python?

ref and out parameters are returned as a tuple in python. In this case, python would get a tuple of (bool, double []) as a return value when calling method(values)

Some overloads do appear to require the StrongBox/Reference approach though:

Thanks for pointing that out. That is a special case when there are overloads to a function and it is not obvious which overload should be used.

1 Like

Yes it’s definitely quite a rare case, with tuple unpacking working really well (and elegantly) with most methods.

Thank you @stevebaer and @AndersDeleuran for answers

The weird stuff is that I get output as a tuple where result is composed from two objects int and double and I still pass a value by reference which actually get never modifies. So the working version looks like this:

    outlines = Array.CreateInstance(Double,0)
    pairs = ON.PInvoke.PythonCollisionDetectionPolygons(PositionsXYZ, PositionsXYZ_N, VertexSums, VertexSums_N, outlines)

I find that if you can make the syntax work well with python, the SDK in general is easier for people to read. In this case, why would you be using a ref; it seems like this should either be an out parameter or be what is returned by the function itself.

In this case I changed to out.
Same result.

It looks not very neat.
Is there other way to do it?
Shall I create a function that returns a tuple?

When you have an out parameter you don’t need to pass anything to the function for that parameter in python. In python you would have

result, pairs = ON.PInvoke.PythonCollisionDetectionPolygons(PositionsXYZ, PositionsXYZ_N, VertexSums, VertexSums_N)

I would also suggest other namespaces than ON and PInvoke, but that is a stylistic preference and not the topic of this thread.

For this function example, I would tend to just return a double[] and have the failure case either return null or an empty array. This completely avoids using a ref or and out parameter.

I keep getting this error:
TypeError: No method matches given arguments for PythonCollisionDetectionPolygons: (<class 'System.Double[]'>, <class 'int'>, <class 'System.Int32[]'>, <class 'int'>)

I am wondering what I am missing when I write this:
public static bool PythonCollisionDetectionPolygons(double[] PositionsXYZ, int PositionsXYZ_N, int[] VertexSums, int VertexSums_N, out int[] pairs, out double[] outlines )
For names I agree, they look very badly named.

I guess there reason it does not work is that I am using CPython with pythonnet package.

I could only make it work with the last answer:
How to use a .NET method which modifies in place in Python? - Stack Overflow

That could very well be the case. pythonnet is ever so slightly different than IronPython in how it interprets things.

1 Like

Thank you :wink: