首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

OpenFileDialog發生問題解决方案

2013-07-20 
OpenFileDialog發生問題小弟完全不知道發生了什麼事,還請各位大大們幫忙!小弟宣告了一個struct如下:[Seria

OpenFileDialog發生問題
小弟完全不知道發生了什麼事,還請各位大大們幫忙!
小弟宣告了一個struct如下:
[Serializable]
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DataType
{
    public float Parameter;
    public float Setting;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
    public float[] Temp;
}
private static DataType MyData;
再宣告一個float[]如下:
private static float[] MyDataFloat = new float[4];
程式寫成按一個Button會開一個OpenFileDialog讓使用者選一個TXT檔,
程式會將TXT檔中的參數寫進float[],
再用以下的程式碼轉成struct,
IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(MyData) / 4);
Marshal.Copy(MyDataFloat, 0, buffer, Marshal.SizeOf(MyData) / 4);
MyData = (DataType)Marshal.PtrToStructure(buffer, MyData.GetType());
Marshal.FreeHGlobal(buffer);
整個動作就只有這樣,
奇怪的問題發生了,
按鍵按第一次沒事,
第二次偶爾沒事,
第三次總是會出現
"嘗試讀取或寫入受保護的記憶體。這通常表示其他記憶體已損毀。"
並且停在這行:
if (opendlg.ShowDialog() != DialogResult.OK) { return; }
小弟完全不知道為什麼?

以下貼出整個Button內的程式,請各位高手幫幫忙,怎麼寫才沒問題?
private void button5_Click(object sender, EventArgs e)
{
    string FilePathName,str;
    OpenFileDialog opendlg = new OpenFileDialog();
    opendlg.Filter = "TXT檔(*.txt)|*.txt|所有檔案(*.*)|*.*";
    if (opendlg.ShowDialog() != DialogResult.OK) { return; }

    // Read TXT File
    StreamReader file = new StreamReader(FilePathName);
    str=file.ReadLine();
    file.Close();

    // 假裝已經拿到TXT的資料了
    MyDataFloat[0] = 0.111F;
    MyDataFloat[1] = 0.222F;
    MyDataFloat[2] = 0.333F;
    MyDataFloat[3] = 0.444F;

    IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(MyData) / 4);
    Marshal.Copy(MyDataFloat, 0, buffer, Marshal.SizeOf(MyData) / 4);
    MyData = (DataType)Marshal.PtrToStructure(buffer, MyData.GetType());
    Marshal.FreeHGlobal(buffer);
}

P.S.
IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(MyData) / 4);
Marshal.Copy(MyDataFloat, 0, buffer, Marshal.SizeOf(MyData) / 4);
MyData = (DataType)Marshal.PtrToStructure(buffer, MyData.GetType());


Marshal.FreeHGlobal(buffer);
以上程式刪掉就沒問題,
可是小弟單獨測試過,
float[]可以完整地將資料寫進struct。


[解决办法]
感觉是大小错了,不要 /4 
[解决办法]


static DataType Data; //全局的
//第一次修改值
        static void TestDataType1()
        {
            fixed (DataType* pd = &Data)
            {
                pd->Parameter = 0.1f;
                pd->Setting = 0.2f;
                pd->Temp[0] = 0.3f;
                pd->Temp[1] = 0.4f;
            }

        }
//第二次,访问值
        static void TestDataType2()
        {
            fixed (DataType* pd = &Data)
            {
                Console.WriteLine(pd->Temp[0]);
            }
        }

[解决办法]
你原来的写法也是可以的,只是这里有些错误
IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(MyData) / 4);这个是分配的字节数,Marshal.SizeOf返回的也是字节数,不能除以4
Marshal.Copy(MyDataFloat, 0, buffer, Marshal.SizeOf(MyData) / 4);这个是复制的长度,第一个参数的类型的数量,第一个参数是float[],长度就是float的个数,所以要字节数除以4。
至于你那一会成功一会报错,那就是因为恰好访问越界内存的时候,那地方被别人用没用着的原因。

热点排行