[StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Unicode)]
    public struct tttsss
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=10)]
        public string name;
    }    [DllImport("a.dll", CharSet = CharSet.Unicode)]
    private static extern void ttaa(ref tttsss);        // dll调用函数
public void dtta()
{
    tttsss hk = new tttsss(); // 为什么编辑器在该语句执行完后看到hk.name还是null?
    ttaa(hk); // 函数对hk没任何操作从该函数出来后hk.name值变成""?
    hk.name = "abcdefghijklmn"; // 该语句结束后不应该是限制10个字节的输入么?怎么直接变成了"abcdefghijklmn"?还是string的被改变了已经不是原来new的内存空间?
}问题1,到底结构的内存空间分配是在什么情况下才实现?问题2,结构内的字符串怎么在C#中修改才保证在分配的内存空间内呢?

解决方案 »

  1.   

    我说说我的意见,抛砖引玉
    MarshalAs是Attribute,Attribute可以认为是捆绑了一些声明Information,这些Information可以在程序需要时利用反射来获得。因此,MarshalAs仅仅在平台调用封送数据(即调用Dll)的那一刻才会起作用(类似于参数的作用),平时可以无视它
    托管环境和非托管环境下的数据传递必须进行锁定或复制。而String类型因其在两种环境下的差异,而必须进行转换及复制(无论是In或Out),指定MarshalAs后,转换及复制在Dll调用及返回时由系统自动完成
      

  2.   

    另外,与StringBuilder不同,C#中String是不可变的,尽管有时看上去可以,实际是编译器创建了一个新字符串,或者是该Sting指向了别的字符序列