简体   繁体   English

C# 中的不安全结构

[英]Unsafe structs in C#

I wanted to try c#'s unsafe 'feature' by creating simple structs (Vector, Particle).我想通过创建简单的结构(向量、粒子)来尝试 c# 的不安全“功能”。

SITUATION情况

I have this 2 structs and want to inject position and velocity vectors into my Particle struct.我有这 2 个结构,想将 position 和速度向量注入我的Particle结构。 As a test I wanted to print out position's X value, but somehow I'm getting random values.作为测试,我想打印出位置的 X 值,但不知何故我得到了随机值。

I have the following code here我这里有以下代码

Vector向量

public readonly struct Vector
{
    public int X { get; }
    public int Y { get; }

    public Vector(int x, int y)
    {
        X = x;
        Y = y;
    }
}

Particle粒子

public unsafe struct Particle
{
    private Vector* mPosition;
    private Vector* mVelocity;

    public Particle(Vector position, Vector velocity = default)
    {
        mPosition = &position; // here is x 10
        mVelocity = &velocity;
    }

    public int GetPosX()
    {
        return mPosition->X; // but here not
    }
}

Program程序

public class Program
{
    private static void Main(string[] args)
    {
        var pos = new Vector(10, 5);
        var obj = new Particle(pos);

        Console.WriteLine(obj.GetPosX()); // prints random value
    }
}

PROBLEM问题

It prints a random value instead of 10.它打印一个随机值而不是 10。

class Program {
    static void Main (string [ ] args) {
        unsafe {
            Vector pos = new Vector(10, 5);
            Particle obj = new Particle(&pos);
            // &pos is at position 0xabcdef00 here.
            // obj.mPosition has a different value here. It points to a different address? Or am I misunderstanding something
            Console.WriteLine(obj.GetPosX( ));
        }
    }
}

public struct Vector {
    public int X;
    public int Y;

    public Vector (int x, int y) {
        X = x;
        Y = y;
    }
}

public unsafe struct Particle {
    private Vector* mPosition;

    public Particle (Vector *position) {
        mPosition = position; // here is x 10
    }

    public int GetPosX ( ) {
        return mPosition->X; // still 10 here
    }
}

This works for me.这对我有用。 Please... do not ask me why it does.请...不要问我为什么会这样。 You will notice that I didn't change that much.你会注意到我并没有改变那么多。 Just calling Particle with *pos instead of pos.只需使用 *pos 而不是 pos 调用 Particle。 For some reason that fixes the problem.由于某种原因可以解决问题。 You have to wrap the code with unsafe then and change the constructor for Particle obviously.然后,您必须使用 unsafe 包装代码并显然更改 Particle 的构造函数。

I could speculate about why it works, but I'd rather not.我可以推测它为什么起作用,但我宁愿不这样做。 Maybe the pointer changes when you pass pos as a parameter for some reason?当您出于某种原因将 pos 作为参数传递时,指针可能会发生变化?

You could not take the ref with right value.您无法获取具有正确值的 ref。

Create a variable like int posX = 10;创建一个变量,如 int posX = 10;

And you can take the reference with variable.您可以使用变量进行引用。 You take the compile time reference and read the runtime reference.您获取编译时参考并阅读运行时参考。

Don't use pointers without fixed.不要使用没有固定的指针。 C# stack performance ise very good. C# 堆栈性能非常好。 You dont need this.你不需要这个。

Usually pointers use with linking (C/Cpp dynamic library linking etc).通常指针与链接一起使用(C/Cpp 动态库链接等)。 If you have large structs (30 bytes and greater) then you can use the ref parameter tag.如果您有大型结构(30 字节或更大),则可以使用 ref 参数标记。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM