Valhalla Legends Forums Archive | .NET Platform | [C#] Returning multiple value types?

AuthorMessageTime
Barumonk
I'm attempting to reproduce this bit of C/C++ code into C#...

[code]#define VectorExpand(v) (v).x, (v).y, (v).z[/code]

... and following code is a basic explanation in C# of how it would idealy work...

[code]public class Vector
{
    public float X;
    public float Y;
    public float Z;

    public Vector(float p_X, float p_Y, float p_Z)  //constructor
    {
        X = p_X;
        Y = p_Y;
        Z = p_Z;
    }
}

public class VectorUtil
{
    public void MethodNumber1()
    {
        MethodNumber3( VectorExpand( MethodNumber2() ) );  //this is my problem
    }

    public Vector MethodNumber2()
    {
        return new Vector(43, 56, 83);  //return a vector
    }

    public void MethodNumber3(float p_X, float p_Y, float p_Z)
    { /***/ }
}[/code]

VectorExpand returns 3 separate floats that aren't in an array. Well, technically its a params type array, but unless I missed something, its not possible to use params like that.  Does anyone know how to duplicate this in C# or maybe within IL code?  I know its possible in MVC++ but I want to avoid the slowdown from marshalling, im going for speed. =/
January 16, 2005, 12:59 AM
Myndfyr
VectorExpand is a macro, not a function, and it doesn't return anything.  Let's say you have the following C function in the same file as VectorExpand:

[code]
float calcDistanceFromVector(float x, float y, float z)
{
  return sqrt( pow(x, 2) + pow(y, 2) + pow(z, 2) );
}
[/code]

Then, you could either:

[code]
float doSomething(Vector& rVec)
{
  float dist;
  dist = calcDistanceFromVector(v.x, v.y, v.z);
  return dist;
}
[/code]

or:

[code]
float doSomething(Vector& rVec)
{
  float dist;
  dist = calcDistanceFromVector( VectorExpand(v) );
  return dist;
}
[/code]
Ultimately, the C Compiler is going to see the exact same code -- the code of the first example.

There is really no reason to use such a macro in C#, and such macros are correspondently not available.
January 16, 2005, 1:38 AM
Barumonk
The reason is that I don't want to pass a reference type that I don't think qualifies as small enough not to cause a performance hit, and I want to keep backwards compatability with another library.  -_-  Although I just realized that it wouldn't matter with this implementation because I would still be passing the reference type to the function that splits it appart.  I also realize its a macro but they aren't possible in C#, its why im calling it a function because thats the only way I can see it in C#.

Anyway, I just fixed it by changing Vector to a struct instead of a class.
January 16, 2005, 1:53 AM
Myndfyr
[quote author=Barumonk link=topic=10206.msg95372#msg95372 date=1105840403]
The reason is that I don't want to pass a reference type that I don't think qualifies as small enough not to cause a performance hit, and I want to keep backwards compatability with another library.  -_-  Although I just realized that it wouldn't matter with this implementation because I would still be passing the reference type to the function that splits it appart.  I also realize its a macro but they aren't possible in C#, its why im calling it a function because thats the only way I can see it in C#.

Anyway, I just fixed it by changing Vector to a struct instead of a class.
[/quote]

If the library function accepts 3 parameters, than your extern statement should contain all three parameters, not one.

If the library function accepts 1 structure parameter, then you should set up your extern functions and structure with the correct interop attributes (MarshalAs, StructLayout, etc).

A macro is not a function in any language.  In this case it is simply a shorthand for accessing the 3 members of a structure.  There is no function in a C library that contains this declaration called VectorExpand.  That macro simply replaces anything within the code with the string:
[code]
(v).x, (v).y, (v).z
[/code]
where (v) is a variable identifier passed into the macro.  The compiler will never, ever, ever see anything called VectorExpand.
January 16, 2005, 2:00 AM
Barumonk
I know -_-;; I'm saying the closest thing possible in C# to a macro is a function that would have a similar return.  I'm just afraid of boxing and unboxing, or passing oversized objects.  I'll probably just get un-lazy and pass x, y, and z.
January 16, 2005, 2:08 AM
Myndfyr
[quote author=Barumonk link=topic=10206.msg95377#msg95377 date=1105841302]
I know -_-;; I'm saying the closest thing possible in C# to a macro is a function that would have a similar return.  I'm just afraid of boxing and unboxing, or passing oversized objects.  I'll probably just get un-lazy and pass x, y, and z.
[/quote]

The only time you have to worry about boxing is:

[code]
int n = 5;
object o = n; // can do this, it's boxing!
[/code]
January 16, 2005, 2:20 AM

Search