I'm attempting to reproduce this bit of C/C++ code into C#...
#define VectorExpand(v) (v).x, (v).y, (v).z
... and following code is a basic explanation in C# of how it would idealy work...
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)
{ /***/ }
}
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. =/
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:
float calcDistanceFromVector(float x, float y, float z)
{
return sqrt( pow(x, 2) + pow(y, 2) + pow(z, 2) );
}
Then, you could either:
float doSomething(Vector& rVec)
{
float dist;
dist = calcDistanceFromVector(v.x, v.y, v.z);
return dist;
}
or:
float doSomething(Vector& rVec)
{
float dist;
dist = calcDistanceFromVector( VectorExpand(v) );
return dist;
}
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.
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 from: Barumonk on January 15, 2005, 07:53 PM
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.
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:
(v).x, (v).y, (v).z
where (v) is a variable identifier passed into the macro. The compiler will never, ever, ever see anything called VectorExpand.
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 from: Barumonk on January 15, 2005, 08:08 PM
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.
The only time you have to worry about boxing is:
int n = 5;
object o = n; // can do this, it's boxing!