public void AddParaString(string paraName, string vi, string vo)
        {
            int span = IntPtr.Size;
            //public IntPtr paraName;
            IntPtr ptr = (IntPtr)((int)CallingInfo.parainfoList + CallingInfo.cnt * SizeOfParaInfo);
            Marshal.WriteIntPtr(ptr, Marshal.StringToCoTaskMemAnsi(paraName));
            //public IntPtr lpvVie;
            ptr = (IntPtr)((int)ptr + span);
            Marshal.WriteIntPtr(ptr, Marshal.StringToCoTaskMemAnsi(vi));
            
            //public IntPtr lpdwSizeVie;
            ptr = (IntPtr)((int)ptr + span);
            //public IntPtr lpvVir;
            ptr = (IntPtr)((int)ptr + span);
            int size = Encoding.GetEncoding(932).GetByteCount(vi);
            Marshal.WriteIntPtr(ptr, Marshal.AllocCoTaskMem(size));
            //public IntPtr lpdwSizeVir;
            ptr = (IntPtr)((int)ptr + span);
            Marshal.WriteInt32(ptr, size);            //public IntPtr lpvVoe;
            //public IntPtr lpdwSizeVoe;
            //public IntPtr lpvVor
            //public IntPtr lpdwSizeVor
            CallingInfo.cnt++;
        }
我知道这是Marshal管理内存....但是,这是什么意思,真的不知道
望各位牛人指教

解决方案 »

  1.   

    Go to definition 去看这个函数的方法说明喽
      

  2.   

    关键是了解知道CallingInfo是啥,其他都不是重要,就是写写数据到非托管的地方
      

  3.   

    Encoding.GetEncoding(932)这样写
    纯粹就是故意搞些不好维护的东西,写成类似Encoding.GetEncoding("GB2312")这样的代码不是更好理解?有病
    谁没事去记那一串数字?
      

  4.   

    Encoding.GetEncoding(932)这样写 
    纯粹就是故意搞些不好维护的东西,写成类似Encoding.GetEncoding("GB2312")这样的代码不是更好理解? 有病 
    谁没事去记那一串数字?-----------------------------------------------------其实很是有些程序员喜欢装B的....
      

  5.   

    这段代码还不如用unsafe写呢,真晕,
      

  6.   

    逐行解释// 获取Win32指针的大小int span = IntPtr.Size; // 下面代码含义是从CallingInfo类中获取名为parainfoList字段的值,
    // 而Para 可能也是一个结构,用于与Win32直接交互
    // SizeOfParaInfo实际上是Marshal.SizeOf(Para) 的值。//这样,CallingInfo.cnt * SizeOfParaInfo 就很好理解了,它是获取
    // 保存在CallingInfo中 Para结构数组的数量 与 单个Para 结构的大小的乘积
    // 但是 (int)CallingInfo.parainfoList 难以理解,
    // 我猜想 前面的 (int) 强制转换告诉我们 parainfoList 属性应该是 IntPtr 类型
    // 这个 parainfoList 是 Para 结构数组在内存中的起始指针
    // 所以,用起始指针加上Para大小与Para数量的乘积,这个明显是指针运算
    // 得到的 ptr 地址就是parainfoList 数组中下一个元素的位置。
     IntPtr ptr = (IntPtr)((int)CallingInfo.parainfoList + CallingInfo.cnt * SizeOfParaInfo); // Marshal.StringToCoTaskMemAnsi(paraName) 很简单,把paraName 这个字符串写入非托管地址
    // 返回值是一个临时变量,变量类型是IntPtr指针,指向的是写入字符串地址的位置。
    // Marshal.WriteIntPtr(ptr, [临时变量]) 
    // 用于将这个刚写入字符串的地址添加到上面说的那个para数组最后一位指针指向的位置。 Marshal.WriteIntPtr(ptr, Marshal.StringToCoTaskMemAnsi(paraName)); 
     //public IntPtr lpvVie; // 这个极佳男,把指针下移一位,
     ptr = (IntPtr)((int)ptr + span); // 与上面的语句类似,把vi 写入
     Marshal.WriteIntPtr(ptr, Marshal.StringToCoTaskMemAnsi(vi)); // 注意,还是指针运算,这次是下移两位
     //public IntPtr lpdwSizeVie; 
     ptr = (IntPtr)((int)ptr + span); 
     //public IntPtr lpvVir; 
     ptr = (IntPtr)((int)ptr + span); // 看出来了,vi字符串内容大概是中文,所以必须获取字符串长度
     int size = Encoding.GetEncoding(932).GetByteCount(vi); 
    // 分配 与 vi 字符串相等的长度,
    // 然后把刚分配的地址的起始指针写入刚才经过指针运算的 ptr 指向的位置中
     Marshal.WriteIntPtr(ptr, Marshal.AllocCoTaskMem(size)); // 指针运算,ptr 指针再次下移一位。
     //public IntPtr lpdwSizeVir; 
     ptr = (IntPtr)((int)ptr + span); // 把刚才计算的vi字符串的大小写入 ptr 指针指向的内存
     Marshal.WriteInt32(ptr, size);  //public IntPtr lpvVoe; 
     //public IntPtr lpdwSizeVoe; 
     //public IntPtr lpvVor 
     //public IntPtr lpdwSizeVor // 告诉 CallingInfo 类,他包含的Para 集合又多了一个 Count++
     CallingInfo.cnt++; // ------ ****************** ------------这个代码如果不使用Win32的代码方式的话,用C# 就一行代码。大概意思是,
    CallingInfo 里头有一个数组,数组是Para的数组,以上代码操作是将
    Para数组的内容就是三个字符串 paraName, vi, vo,这个代码的作用就是将三个字符串加入数组,形成一个新的para结构。并修改指针。但是非常奇怪,方法参数本来有 paraName, vi, vo  三个参数,但仅仅使用了前两个,vo没有用,大概不全。