C# 在不同编译下的不同表现

  这是我在2018年的时候发在Unity Forums上的帖子, 至今无人回复, 之前是想用TypedReference做DataTable的相关功能的, 可是结果不正确.

tiancaiwrkOct 18, 2018 

System.TypedReference bugged? can't figure out how to use it !!!

C# has some way to get Generic Type target pointer, such as GCHandle / Marshal,
this time I want to use System.TypedReference for getting pointer of any struct, bug I think it's bugged...
I dont know how to report a BUG to Unity, just post it here
here is the code, it works in VS project but not unity project:
复制代码
    void Start()
    {
        int v1 = 100;
        int v2 = 1000;
 
        var m1 = __makeref(v1);
        var m2 = __makeref(v2);
 
        var val1 = __refvalue(m1, int);     // val1 is 100
        var val2 = __refvalue(m2, int);     // val2 is 1000
 
        Debug.Log(val1);
        Debug.Log(val2);
 
        unsafe
        {
            *(IntPtr*)(&m1) = new IntPtr((void*)&v2); // 这里应该是把m1的值改变了的 m1应该为1000
 
            val1 = __refvalue(m1, int);     // val1 is 100 -- not changed 可是这里m1赋值没有变换, 还是100
            val2 = __refvalue(m2, int);     // val2 is 1000
 
            Debug.Log(val1);
            Debug.Log(val2);
 
            var ptr = *(IntPtr*)(&m1);
            var p = (int*)ptr.ToPointer();
            var data = *p;                  // data is 1000 -- changed 奇怪的是这里得到的m1的值又是1000
 
            Debug.Log(data);
        }
    }
复制代码
And what's more, if I dont Set the pointer of m1, the value of [data] is Strange!!
复制代码
    void Start()
    {
        int v1 = 100;
        int v2 = 1000;
 
        var m1 = __makeref(v1);
        var m2 = __makeref(v2);
 
        var val1 = __refvalue(m1, int);     // val1 is 100
        var val2 = __refvalue(m2, int);     // val1 is 1000
 
        Debug.Log(val1);
        Debug.Log(val2);
 
        unsafe
        {
            var ptr = *(IntPtr*)(&m1);
            var p = (int*)ptr.ToPointer();
            var data = *p;                  // data is 536019728 [random] -- WTF 更奇怪的是直接取m1的值, 居然不对
 
            Debug.Log(data);
        }
    }
复制代码
This issue is happened in unity project, it works as expected in VS project.
the VS project value is :
复制代码
 
        static unsafe void TT()
        {
            int v1 = 100;
            int v2 = 1000;
 
            var m1 = __makeref(v1);
            var m2 = __makeref(v2);
 
            var val1 = __refvalue(m1, int);     // val1 is 100
            var val2 = __refvalue(m2, int);     // val2 is 1000
 
            unsafe
            {
                *(IntPtr*)(&m1) = new IntPtr((void*)&v2);  // m1值被赋值1000
 
                val1 = __refvalue(m1, int);     // val1 is 1000 VS工程编译的话, 这个m1值赋值正确的 1000
                val2 = __refvalue(m2, int);     // val2 is 1000
 
                var ptr = *(IntPtr*)(&m1);
                var p = (int*)ptr.ToPointer();
                var data = *p;                  // data is 1000 这里也是正确的
            }
        }
复制代码

  这个也是偶然想到极限速度对变量赋值的时候看到的做法, 测试以后发现不对劲. 以前大部分时候程序出错我们都会先想到是自己代码写错了, 不过这里可以看出

编译器也是有错的时候的......

===============================

又碰到一个, 版本为Unity2019了, 使用 Task 的 Wait() 方法会造成卡死...

复制代码
    [MenuItem("Test/RunUpdate")]
    public async static void TestRun()
    {
        try
        {
            Run().Wait();  // 必须使用 await Run();
        }
        catch(Exception ex)
        {
            Debug.LogError(ex.Message);
        }
    }
    
    private static async Task Run()
    {
        System.IO.FileStream fs = new System.IO.FileStream(@"C:\Users\xxxx\Desktop\Test\test.txt", System.IO.FileMode.Create);
        string str = @"Hello World!!!";
        var buffer = System.Text.Encoding.UTF8.GetBytes(str);
        await fs.WriteAsync(buffer, 0, buffer.Length);
        Debug.Log("End");
    }
复制代码

 

posted @   tiancaiKG  阅读(237)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示