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

  • 相关阅读:
    HDU 5528 Count a * b 欧拉函数
    HDU 5534 Partial Tree 完全背包
    HDU 5536 Chip Factory Trie
    HDU 5510 Bazinga KMP
    HDU 4821 String 字符串哈希
    HDU 4814 Golden Radio Base 模拟
    LA 6538 Dinner Coming Soon DP
    HDU 4781 Assignment For Princess 构造
    LA 7056 Colorful Toy Polya定理
    LA 6540 Fibonacci Tree
  • 原文地址:https://www.cnblogs.com/millionsmultiplication/p/12718162.html
Copyright © 2011-2022 走看看