討論區快速選單
知識庫快速選單
傑米的攝影旅遊筆記 網路投保旅行平安險
[ 回上頁 ] [ 討論區發言規則 ]
建立記憶體問題
更改我的閱讀文章字型大小
作者 : love007002(爆走笨魚)
[ 貼文 35 | 人氣 1891 | 評價 0 | 評價/貼文 0 | 送出評價 3 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2016/2/16 下午 04:47:17
我有兩隻DLL檔, 其中一隻是用來建立記憶體及讀寫, 另一隻DLL則是呼叫. 以下如我的範例

第一支呼叫建立及讀寫範例

ShareMemInit(ShareMemName, DataSize);

PLCToShareMem(Data, this.Name.Trim() + "_" + this.UnitNo.Trim());

第二支則是運作建立及讀取

public int ShareMemInit(string ShareMemName, long DataSize)//DataSize is Data Count.
     {
     bool b_ShareMemAlreadyExist = false;
     bool b_ShareMemFalgAlreadyExist = false;
     int Result = -1;
     long lngSize = DataSize * sizeof(Int16);

     if (lngSize <= 0 || lngSize > 0x00800000 || ShareMemName.Trim().Length == 0)
     {
     Communication_Log_Management_Editor.Communication_Log_Management_Editor.Log("ShareData.MemInit() Fail\n參數錯誤." + "ShareMemoryName: " + ShareMemName + " Size: " + lngSize, System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
     return 1; //参数错误
     }

     if (ShareMemName.Trim().Length > 0)
     {
     //创建内存共享体(INVALID_HANDLE_VALUE)
     IntPtr m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)lngSize, ShareMemName);
     if (m_hSharedMemoryFile == IntPtr.Zero)
     {
     b_ShareMemAlreadyExist = false;
     Communication_Log_Management_Editor.Communication_Log_Management_Editor.Log("ShareData.MemInit() Fail\n創建共享體失敗." + "ShareMemoryName: " + ShareMemName + " Size: " + lngSize + ". ErrorCode: " + GetLastError(), System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
     return 2;//创建共享体失败
     }
     else
     {
     if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建
     {
     b_ShareMemAlreadyExist = true;
     }
     else //新创建
     {
     b_ShareMemAlreadyExist = false;
     }
     }
     //---------------------------------------
     //创建内存映射
     IntPtr m_pwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, (uint)lngSize);
     if (m_pwData == IntPtr.Zero)
     {
     CloseHandle(m_hSharedMemoryFile);
     Communication_Log_Management_Editor.Communication_Log_Management_Editor.Log("ShareData.MemInit() Fail\n創建內存映射失敗." + "ShareMemoryName: " + ShareMemName + " Size: " + lngSize + ". ErrorCode: " + GetLastError(), System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
     return 3; //创建内存映射失败
     }
     else
     {
     if (b_ShareMemAlreadyExist == false)
     {
     //初始化
     }

     Result = 0;
     }
     //----------------------------------------
     }


     if (Result == 0)
     {
     String ShareMemFalgName = ShareMemName.Trim() + "_Status";

     IntPtr m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)(sizeof(Int16) * 2), ShareMemFalgName);
     if (m_hSharedMemoryFile == IntPtr.Zero)
     {
     b_ShareMemFalgAlreadyExist = false;
     Communication_Log_Management_Editor.Communication_Log_Management_Editor.Log("ShareData.MemInit() Fail\n創建共享體失敗." + "ShareMemoryName: " + ShareMemFalgName + " Size: " + (sizeof(Int16) * 2) + ". ErrorCode: " + GetLastError(), System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
     return 2;//创建共享体失败
     }
     else
     {
     if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建
     {
     b_ShareMemFalgAlreadyExist = true;
     }
     else //新创建
     {
     b_ShareMemFalgAlreadyExist = false;
     }
     }

     //---------------------------------------
     //创建内存映射
     IntPtr m_pwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, (uint)(sizeof(Int16) * 2)); //[0]:Connect Status, [1]: Write Status
     if (m_pwData == IntPtr.Zero)
     {
     CloseHandle(m_hSharedMemoryFile);
     Communication_Log_Management_Editor.Communication_Log_Management_Editor.Log("ShareData.MemInit() Fail\n創建內存映射失敗." + "ShareMemoryName: " + ShareMemFalgName + " Size: " + (sizeof(Int16) * 2) + ". ErrorCode: " + GetLastError(), System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
     return 3; //创建内存映射失败
     }
     else
     {
     if (b_ShareMemFalgAlreadyExist == false)
     {
     //初始化
     }
     }
     }

     return 0; //创建成功
     }

 public int PLCToShareMem(Int16[] WData, String ShareMemName) //WData is PLC Real Value
     {
     String PlcMonitorAddrStart_1 = "-1";
     String PlcMonitorSize_1 = "-1";
     String PlcMonitorAddrStart_2 = "-1";
     String PlcMonitorSize_2 = "-1";
     int DataSize = 0;

     String CurrentDirectoryStr = System.Environment.CurrentDirectory;
     String Config_Dir = CurrentDirectoryStr + "\\Config\\";
     String PLCSetFileName = "PLCConfig.csv";
     String PLCSetFilePath = Config_Dir + PLCSetFileName;

     if (!File.Exists(PLCSetFilePath))
     {
     string strPath = @"C:\\";

     DirectoryInfo di = new DirectoryInfo(strPath);
     foreach (FileInfo fileName in di.GetFiles("*.csv", SearchOption.AllDirectories))
     {
     if (fileName.Name.Trim() == PLCSetFileName.Trim())
     {
     PLCSetFilePath = fileName.FullName;
     break;
     }
     }
     }

     if (File.Exists(@PLCSetFilePath))
     {
     StreamReader SR = null;

     try
     {
     SR = new StreamReader(@PLCSetFilePath);

     string Line;
     while ((Line = SR.ReadLine()) != null)
     {
     String[] LineArray = Line.Split(',');

     if (LineArray[0].Trim().ToUpper() == "UnitNo".Trim().ToUpper())
     {
     continue;
     }

     if (LineArray[1].Trim() == ShareMemName.Trim())
     {
     PlcMonitorAddrStart_1 = LineArray[4].Trim();
     PlcMonitorSize_1 = LineArray[5].Trim();
     PlcMonitorAddrStart_2 = LineArray[6].Trim();
     PlcMonitorSize_2 = LineArray[7].Trim();

     if ((PlcMonitorAddrStart_1.Trim() != "-1") && (PlcMonitorSize_1.Trim() != "-1"))
     {
     DataSize = DataSize + Convert.ToInt32(PlcMonitorSize_1);
     }

     if ((PlcMonitorAddrStart_2.Trim() != "-1") && (PlcMonitorSize_2.Trim() != "-1"))
     {
     DataSize = DataSize + Convert.ToInt32(PlcMonitorSize_2);
     }
     break;
     }
     }
     }
     catch (Exception ex)
     {
     PlcMonitorAddrStart_1 = "-1";
     PlcMonitorSize_1 = "-1";
     PlcMonitorAddrStart_2 = "-1";
     PlcMonitorSize_2 = "-1";
     DataSize = 0;
     Communication_Log_Management_Editor.Communication_Log_Management_Editor.Log(ShareMemName + " PLCToShareMem Fail. Read PLCConfig File Fail." + ex.Message, System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
     }
     finally
     {
     if (SR != null)
     {
     SR.Close();
     }
     }

     if ((ShareMemName.Trim() != "") && (ShareMemName.Trim() != "-1"))
     {
     IntPtr m_hSharedMemoryFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, ShareMemName);

     if (m_hSharedMemoryFile == IntPtr.Zero)
     {
     Communication_Log_Management_Editor.Communication_Log_Management_Editor.Log(ShareMemName + " PLCToShareMem Fail. Unable to open file mapping. ErrorCode: " + GetLastError(), System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
     return 1;
     }

     if (DataSize == 0)
     {
     Communication_Log_Management_Editor.Communication_Log_Management_Editor.Log(ShareMemName + " PLCToShareMem Fail. DataSize is 0.", System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
     return 1;
     }

     IntPtr m_pwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, (uint)(DataSize * sizeof(Int16)));


     if (m_pwData == IntPtr.Zero)
     {
     Communication_Log_Management_Editor.Communication_Log_Management_Editor.Log(ShareMemName + " PLCToShareMem Fail. Unable to read shared memory. ErrorCode: " + GetLastError(), System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
     return 2;
     }

     Marshal.Copy(WData, 0, m_pwData, DataSize);
     return 0;
     } //if ((ShareMemName.Trim() != "") && (ShareMemName.Trim() != "-1"))
     } // if (File.Exists(@PLCSetFilePath))
     return 3;
     }

問題如下: 建立好記憶體後, 會有一個TIMER(1秒)持續呼叫 PLCToShareMem(Data, this.Name.Trim() + "_" + this.UnitNo.Trim());
大約跑不到3分鐘, 那隻PLCToShareMem() 的函數就會回傳 2, 而我擷取GetLastError()代碼會是8. 我查了一下代碼8代表記憶體存取空間不足, 這讓我有點不知道為什?
因為如果假設記憶體空間不足, 應該是我一開始建立好後再寫記憶體就會導致錯誤, 為何會是跑了幾分鐘後才會出現這狀況.
另外我也在想問為何我每在呼叫 PLCToShareMem(), 裡面的 hSharedMemoryFile 及 m_pwData 的數值都不一樣, 不是相同記憶體指向的會是同一個嗎??
是否可請各位大大幫我解惑, 還是我寫的方式是錯的??
 板主 : 小朱
 > C# - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - C# - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
C#
1 小朱 6270 
2 蹂躪 2700 
3 HKLN.net 2440 
4 marlon 2130 
5 joe 1320 
6 識丁 910 
7 好說 860 
8 愛睏魚 770 
9 總幹事 720 
10 Demonbane 600 
C#
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2018 程式設計俱樂部 http://www.programmer-club.com.tw/
0.03125