【问题标题】:Unsafe structs in C#C# 中的不安全结构
【发布时间】:2020-04-15 22:38:43
【问题描述】:

我想通过创建简单的结构(向量、粒子)来尝试 c# 的不安全“功能”。

情况

我有这 2 个结构,想将位置和速度向量注入我的 Particle 结构。 作为测试,我想打印出位置的 X 值,但不知何故我得到了随机值。

我这里有以下代码

矢量

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

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

粒子

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
    }
}

计划

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
    }
}

问题

它打印一个随机值而不是 10。

【问题讨论】:

标签: c# pointers struct unsafe


【解决方案1】:
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
    }
}

这对我有用。 请...不要问我为什么会这样。你会注意到我并没有改变那么多。只需使用 *pos 而不是 pos 调用 Particle。由于某种原因可以解决问题。你必须用 unsafe 包装代码,然后显然更改 Particle 的构造函数。

我可以推测它为什么起作用,但我宁愿不这样做。也许当您出于某种原因将 pos 作为参数传递时,指针会发生变化?

【讨论】:

  • 是的,这有点奇怪,但是我会选择第一种解决方案,因为它允许我在安全的上下文中使用我的粒子。
  • @Hrant 我想知道下面的地址是否代替了 main() 中的 unsafe public int GetPosX ( ) { unsafe { return mPosition->X; } }
【解决方案2】:

您无法获取具有正确值的 ref。

创建一个变量,如 int posX = 10;

您可以使用变量进行引用。您获取编译​​时参考并阅读运行时参考。

不要使用没有固定的指针。 C# 堆栈性能非常好。你不需要这个。

通常指针与链接一起使用(C/Cpp 动态库链接等)。如果您有大型结构(30 字节或更大),则可以使用 ref 参数标记。

【讨论】:

  • 感谢您的帮助。建议的解决方案不是超级干净,但它有效。
猜你喜欢
  • 2018-06-06
  • 2011-01-22
  • 2021-01-27
  • 1970-01-01
  • 2018-02-17
  • 1970-01-01
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多