天天看點

關于VS2005與EVC4.2的項目開發過程中的問題點滴

        這段時間一直緻力于嵌入式IOServer與嵌入式HMI的開發,這中間及牽扯C#與EVC通信的問題,也牽扯EVC本身開發遇到的一些問題。

        1、EVC與C#資料傳遞

        我是用EVC做DLL(MFC 擴充DLL),C#直接調用。

       這是EVC DLL的接口

       DLLEXPORT long WINAPI IOMReadData(LPTSTR,LPTSTR);         //讀記憶體資料  變量名稱  資料

       DLLEXPORT long WINAPI IOMWriteData(LPTSTR,LPTSTR);          //寫記憶體資料  變量名稱

       這是C#的接口聲明

        [DllImport(@"/Storage Card/YFIOES.dll")]

        public static extern int IOMReadData(string strName, StringBuilder strData);

        [DllImport(@"/Storage Card/YFIOES.dll")]

        public static extern int IOMWriteData(string strName, string strData);

        這裡面遇到幾個有意思的問題:對于字元串類型一直是資料傳遞的問題頻發地帶,在EVC接口中聲明CString 與 CString & 接口時發現字元串能傳遞下去,可是返不回來,聲明成LPTSTR類型,發現如果C#接口為string ,則messagebox可以顯示該字元串,但是傳遞到textbox控件中則為空,聲明為StringBuilder則就沒有任何問題。

       這裡有一個需要注意的問題:當傳回的字元串大于16個字長度時,如下聲明StringBuilder strData=new StringBuilder(); 要修改為StringBuilder strData=new StringBuilder(255); 否則會報錯,我就是在這個問題上調試了半天,我還以為我的DLL出問題了呢。

       2、EVC與INI檔案

       在EVC中是不支援INI讀寫的API的,幸好有網絡,查了一個,還挺好使。

DWORD CYFIOMEM::GetPrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpDefault,LPTSTR lpReturnedString,DWORD nSize,LPCTSTR lpFileName )

{

  CFile iniFile;

  PBYTE pFileBuf;

  CString szBuf;

  DWORD dwLength;

  if( lpReturnedString == NULL )return 0;

  if( lpDefault ) {_tcscpy( lpReturnedString,lpDefault ); }

  else {_tcscpy( lpReturnedString,TEXT( "/0" )); }

  if (lpFileName == NULL ){return _tcslen( lpReturnedString );} 

  if(!iniFile.Open(lpFileName, CFile::modeRead)) {return _tcslen( lpReturnedString );}

  dwLength = iniFile.GetLength();

  if (dwLength == 0) { return _tcslen( lpReturnedString );}

  pFileBuf = new BYTE[dwLength + 2];

  if (pFileBuf == NULL) { return _tcslen( lpReturnedString );}

  memset(pFileBuf, 0x0, dwLength + 2);

  iniFile.Read((void *)pFileBuf, dwLength);

  iniFile.Close();

  if (pFileBuf[0] == 0xFF && pFileBuf[1] == 0xFE) {szBuf = (LPCWSTR)(pFileBuf + 2);}

  else

  {

   PTCHAR pszWideChar = new TCHAR[dwLength + 1];

   MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pFileBuf, dwLength, pszWideChar, dwLength);

   szBuf = pszWideChar;

   delete pszWideChar;

  }

  delete pFileBuf;

  while (1)

   CString szTemp;

   int nPos;

   if (szBuf.IsEmpty()) return _tcslen( lpReturnedString );

   nPos = szBuf.FindOneOf(TEXT("/r/n"));

   if (nPos == -1)

   {

    szTemp = szBuf;

    szBuf.Empty();

   }

   else

    szTemp = szBuf.Left(nPos);

    szBuf = szBuf.Right(szBuf.GetLength() - nPos);

    szBuf.TrimLeft(TEXT("/r/n"));

   } 

   szTemp.TrimLeft(TEXT("/t "));

   szTemp.TrimRight(TEXT("/t "));

   if (szTemp.GetAt(0) == TEXT('[') && szTemp.GetAt(szTemp.GetLength() - 1) == TEXT(']'))

    szTemp = szTemp.Right(szTemp.GetLength() - 1);

    szTemp = szTemp.Left(szTemp.GetLength() - 1);

    if (lpAppName == NULL)

    {

  return _tcslen( lpReturnedString );                

    }

    else if (szTemp.CompareNoCase(lpAppName) == 0)

  while (1)

  {

   if (szBuf.IsEmpty()) {continue; }    

   nPos = szTemp.Find(TEXT("="));

   if (nPos == -1) {return _tcslen( lpReturnedString );}

   CString szTemp1;

   szTemp1 = szTemp.Left(nPos);

   szTemp1.TrimLeft(TEXT("/t "));

   szTemp1.TrimRight(TEXT("/t "));

   if (lpKeyName == NULL)  {return _tcslen( lpReturnedString  );}

   else if (szTemp1.CompareNoCase(lpKeyName) == 0)

    szTemp1 = szTemp.Right(szTemp.GetLength() - nPos - 1);

    szTemp1.TrimLeft(TEXT("/t "));

    szTemp1.TrimRight(TEXT("/t "));

    _tcscpy( lpReturnedString,szTemp1 );

    return _tcslen( lpReturnedString );

  }

  return _tcslen( lpReturnedString );

}

       3、在EVC中寬字元是我最頭疼的,建議最好多用CString,能有效回避該問題。

       在開發過程中一定還會遇到各種各樣的問題,有時間再一一寫來... ...