zoukankan      html  css  js  c++  java
  • C# 中size_t的暗坑

    最近在接SDK,在写DllImport遇到一个神奇的暗坑

    export代码和DLLImport

    #if defined(_WIN32) || defined(_WIN64)
    
    #define __DLLEXPORT__ __declspec(dllexport)
    
    #else
    
    #define __DLLEXPORT__
    
    #endif
    
    extern "C"
    {
    	__DLLEXPORT__
    	void Init(size_t* requiredSize,char* buff)
    	{
    		....
    	}
    
    }
    
     [DllImport("SDK")]
        public static extern void Init(ref int requiredSize);
    

    DLL是64位,测试代码如下

    int a = 1;
    StringBuilder sb = new StringBuilder(1024);
    Init(ref a, sb);
    print(a);print(sb);
    

    结果惊奇的发现sb = NULL

    换了段测试代码

    int a = 1;
    StringBuilder sb1 = new StringBuilder(1024);
    StringBuilder sb2 = new StringBuilder(1024);
    Init(ref a, sb2);
    print(a);print(sb1);print(sb2);
    

    发现sb2的数据是正常的,sb1依旧是NUll

    和同事研究了一下,最后发现是DllImport写得不对

    换成以下写法就正常了

     [DllImport("SDK")]
    public static extern void Init(ref UIntPtr requiredSize);
    

    导致这个bug的原因是因为size_t的跨平台性,C#下于它匹配的数据类型是UIntPtr,同样可以做到32位系统是4字节,64位系统是8字节,而且都是Unsigned Int

    原来的写法之所以会出现异常奇怪的bug是因为c++的方法会将requiredSize置空后再赋值。

    而C#下由于a和sb数据是连续的,2个加起来字节数才能和size_t对等,结果导致了sb也被置空,真是危险的c++

  • 相关阅读:
    为什么new的普通数组用delete 和 delete[]都能正确释放
    虚幻4属性系统(反射)
    CFileDialog类的默认路径
    把单一元素的数组放在一个struct的尾端
    在UE4中使用SVN作为source control工具
    单精度浮点数和有效位数为什么是7位
    Valid Number--LeetCode
    归并排序
    堆排序
    直接选择排序
  • 原文地址:https://www.cnblogs.com/millionsmultiplication/p/12718162.html
Copyright © 2011-2022 走看看