大虾们好,我想请教一个问题。我想在c#里面实现和c语言的struct 功能一样的有固定长度的数据结构,在网上查了相关讨论和资料,发现应该这么写:
[StructLayout(LayoutKind.Sequential)]
        public struct MSTRUCT
        {
            [MarshalAs(UnmanagedType.AnsiBStr)]
            public char ch;
            [MarshalAs (UnmanagedType .LPStr ,SizeConst =8)]
            public string word;
            [MarshalAs (UnmanagedType .I4 )]
            public int wordlen;
            [MarshalAs(UnmanagedType.LPStr, SizeConst = 24)]
            public string sentence1;
            [MarshalAs(UnmanagedType.LPStr, SizeConst = 24)]
            public string sentence2;
            [MarshalAs(UnmanagedType.LPStr, SizeConst = 24)]
            public string sentence3;
            [MarshalAs(UnmanagedType.I4)]
            public int len;
        }我定义好这个结构之后,在按钮点击的时候希望做一些工作,其中由一个步骤是获取这个struct的大小,我用的是marshal.sizeof,
具体的前半部分代码如下:
 FileStream fs = new FileStream("字义.txt", FileMode.Append);
            MSTRUCT struct1 = new MSTRUCT();
            int length;
            if (this.textBox1.Text != null && this.textBox2.Text != null && this.textBox3.Text != null)
            {
                struct1.ch = Convert.ToChar(this.textBox1.Text);
                struct1.word = this.textBox2.Text;
                struct1.sentence1 = this.textBox3.Text;
            }
            else 
            {
                MessageBox.Show("请输入至少汉字、组词及例句1");
            }
            if (this.textBox4.Text != null)
                struct1.sentence2 = this.textBox4.Text;
            else
                struct1.sentence2 = this.textBox3.Text;            if (this.textBox5.Text != null)
                struct1.sentence3 = this.textBox5.Text;
            else
                struct1.sentence3 = this.textBox3.Text;           // fs.Write(struct1, 0, sizeof(struct1));            struct1.wordlen = struct1.word.Length;            length = Marshal.SizeOf(typeof (MSTRUCT ) );但是到了红色的这句话的时候报以下这个异常:
类型“生成文件.Form1+MSTRUCT”不能作为非托管结构进行封送处理;无法计算有意义的大小或偏移量。
异常的具体信息为:未处理 System.ArgumentException
  Message="类型“生成文件.Form1+MSTRUCT”不能作为非托管结构进行封送处理;无法计算有意义的大小或偏移量。"
  Source="mscorlib"
  StackTrace:
       在 System.Runtime.InteropServices.Marshal.SizeOf(Type t)
       在 生成文件.Form1.button1_Click(Object sender, EventArgs e) 位置 D:\My Documents\Visual Studio 2005\Projects\生成文件\生成文件\Form1.cs:行号 94
       在 System.Windows.Forms.Control.OnClick(EventArgs e)
       在 System.Windows.Forms.Button.OnClick(EventArgs e)
       在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       在 System.Windows.Forms.Control.WndProc(Message& m)
       在 System.Windows.Forms.ButtonBase.WndProc(Message& m)
       在 System.Windows.Forms.Button.WndProc(Message& m)
       在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       在 System.Windows.Forms.Application.Run(Form mainForm)
       在 生成文件.Program.Main() 位置 D:\My Documents\Visual Studio 2005\Projects\生成文件\生成文件\Program.cs:行号 17
       在 System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
       在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       在 System.Threading.ThreadHelper.ThreadStart()有大侠能帮忙解决这个小问题吗~~谢谢啊~~感激不尽·~~急~~~

解决方案 »

  1.   

    struct不是类,个人感觉是不是应该按值类型进行封送?
      

  2.   

    应该不是这个问题吧。。因为我有看到struct类型的这样子做的啊
      

  3.   

    Struct和Class的区别:
    struct成员默认访问权限是public,而class是private, struct 还是值类型,而 class 是对象类型....length = Marshal.SizeOf(typeof (MSTRUCT ) ); 中,在用Marshal.SizeOf方法时,会发生两种异常...1. ArgumentException-------typeof 的参数是泛型类型。
    2.ArgumentNullException----typeof 的参数为 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing).因为struct 还是值类型,所以在typeof (MSTRUCT )中,报异常, 如果struct 改成class,不会报异常..lz试一下...
    如果非要想用struct的话,typeof (MSTRUCT )中的MSTRUCT先强行转换类型之后,再用...
      

  4.   


    我按照楼上的做了,把struct改成了class,但是还是会报异常啊。。楼上说的typeof (MSTRUCT )中的MSTRUCT先强行转换类型之后,再用... 
    能具体写一下吗??谢谢啊~~
      

  5.   

    应为你的结构布局可能是不连续的
    try 每个字段
    加上filedoffset属性
      

  6.   

    另外你的结构定义的有问题
    第一个字段你用bstr修饰代表的是一个字符串可是第一个字段又是定义为一个字符
      

  7.   

    不好意思啊~前几天有事,都没来
    可以参考这一篇啊,开头就说sequencial是可以按照连续的内存布局的啊~
    http://blog.csdn.net/MasterFT/archive/2007/07/19/1699009.aspx
    我第一个字段其实是想定义为一个字符的但不知道该怎么写。。
      

  8.   

    谢谢倦怠,我用explicit就不报异常了。。谢谢了~ 虽然还有别的问题,不过这个问题解决了,结贴~~
      

  9.   

    谢谢倦怠,我用explicit就不报异常了。。谢谢了~ 虽然还有别的问题,不过这个问题解决了,结贴~~