這段時間一直緻力于嵌入式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,能有效回避該問題。
在開發過程中一定還會遇到各種各樣的問題,有時間再一一寫來... ...