一、將過去的工程用VS2010打開的時候。你有可能會遇到一大堆的警告:warning C4996。
好比:warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
緣由是Visual C++ 2005使用了更加安全的run-time library routines。
新的Security CRT functions(就是那些帶有「_s」後綴的函數):
http://msdn2.microsoft.com/en-us/library/wd3wzwts(VS.80).aspx
那麼如何搞定這些警告呢: html
緣由解釋
這種微軟的警告,主要由於那些C庫的函數,不少函數內部是不進行參數檢測的(包括越界類的),微軟擔憂使用這些會形成內存異常,因此就改寫了一樣功能的函數,改寫了的函數進行了參數的檢測,使用這些新的函數會更安全和便捷。關於這些改寫的函數你不用專門去記憶,由於編譯器對於每一個函數在給出警告時,都會告訴你相應的安全函數,查看警告信息就能夠獲知,在使用時也再查看一下MSDN詳細瞭解。庫函數改寫例子:
mkdir改寫爲 _mkdir
fopen」改寫爲 fopen_s
stricmp改寫爲 stricmp_s
sprintf改寫爲sprintf_s mysql
strcpy改寫爲strcpy_s
解決方案:
1> 根據下面的warning提示:參見「fopen」的聲明
消息:「This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.」
因此能夠將函數按warning提示的第二句,改成使用fopen_s函數便可:
例如:FILE *pFile=fopen("1.txt", "w");
改成:
FILE* pFile;
fopen_s(&pFile, "1.txt", "w");
2> 仍是根據warning提示的地三句話:use _CRT_SECURE_NO_DEPRECATE
項目|屬性|配置屬性|C/C++|命令行|附加選項,加入【/D "_CRT_SECURE_NO_DEPRECATE" 】(注:加入中括號中完整的內容)
3> 下降警告級別:項目|屬性|配置屬性|C/C++|常規,本身根據狀況下降警告級別(此法不推薦)
注意:高度重視警告:使用編譯器的最高警告級別。應該要求構建是乾淨利落的(沒有警告)。理解全部警告。經過 修改代碼而不是下降警告級別來排除警告。
方法一:手工將原來的舊函數替換成新的Security CRT functions。
方法二:屏蔽這個警告。
在預編譯頭文件stdafx.h裏(注意:必定要在沒有include任何頭文件以前)定義下面的宏:
#define _CRT_SECURE_NO_DEPRECATE
或者#param warning(disable:4996)
方法二沒有使用新的更安全的CRT函數,顯然不是一個值得推薦的方法,但是你又不想一個一個地改。
那麼還有一個更方便的方法:
在預編譯頭文件stdafx.h裏(一樣要在沒有include任何頭文件以前)定義下面的宏:
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
在連接的時候便會自動將舊函數替換成Security CRT functions。
注意:這個方法雖然使用了新的函數,可是不能消除警告你還得同時使用方法二。。。 c++
二、SerialPort收數據時出現的BUGcomstat is being used without defining sql
好比:Run-Time Check Failure #3 - The variable 'comstat' is being used without being initialized. 編程
CSerialPort類在Visual C++ .NET 應用時會出現意想不到的問題。以《Visual C++/Turobo C串口通訊編程實踐》(龔建偉 熊光明 著)一書中第二章的SerialPortTest程序爲例,當在Visual C++ .NET下編寫後以後,debug以後,會出現編譯錯誤:「operator+="不明確,MSDN解釋「爲重載運算符定
義了多個可能的運算符。可能的解決方案:對一個或多個實際參數使用顯式轉換。」當將 windows
LONG CSerialPortTestDlg::OnComm(WPARAM ch, LPARAM port)
{
m_strEditReceiveMsg +=ch;
UpdateData(FALSE); //將接收到的字符顯示在接收編輯框中
return 0;
} 安全
中m_strEditReceiveMsg +=ch;改寫爲m_strEditReceiveMsg +=char(ch);後,debug順利經過了。其實這個還不是CSerialPort類的問題。m_strEditReceiveMsg+=ch;改寫爲m_strEditReceiveMsg +=char(ch) 是應該的,這樣更爲嚴謹,由於在 OnComm(WPARAM ch, LPARAM port)函數中,ch 爲 WPARAM 型數據,WPARAM型數據適應型很強,char(ch)將ch強制轉換爲char型,更適合CString型,這應該算是VC.NET的進步。 服務器
當將這個問題解決以後,編譯成功了。而後開始測試。向串口調試助手發送消息時一切正常。但從串口調試助手向SerialPortTest發送消息時,報錯了,說「comstat is being used without defining",在SerialPort.CPP中,能夠找到comstat的定義:COMSTAT comstat; 但將光標指向comstat時右鍵轉到定義處或聲明處,卻均提示「未定義符號」,這即是CSerialPort類在VC.NET應用中的問題了。那該如何解決這個問題呢?在這,咱們向你們提供兩種解決方案: socket
方案1: 改變項目配置屬性 ide
一種解決方案是改變基本運行時檢查(changing the runtime checks in project settings):在菜單Project->Project properties-> C/C++ -> Code generation-> Basic Runtime checks --> change to 'Default',在中文版中是:項目-〉屬性-〉配置屬性-〉C/C++代碼生成-〉基本運行時檢查-〉設置爲默認,當將基本運行時檢查改成默認以後,編譯天然順利經過了,向串口調試助手發送消息正常了,再從串口調試助手向SerialPortTest發送消息時,也正常了。
方案2:改變comstat變量屬性
另外一種解決方案是將CSerialPort.CPP中的COMSTAT comstat;改成static COMSTAT comstat;這樣改了以後,debug順利經過,而後調試,與串口調試助手相互發消息都OK了。爲何這樣就能解決呢?其實當你使用debug解決方案時,它的基本運行時檢查初始設置爲:二者(/RTC1,等同於 /RTCsu),這個二者是指:堆棧幀(/RTCs),未初始化的變量(/RTCu)。因爲它要檢查未初始化的變量,因此將SerialPort.cpp中的COMSTAT comstat;改成static COMSTAT comstat;就能夠正常使用CSerialPort類了。
以上是在debug下的解決方案,當在Release編譯狀態時,你會發現並不須要將COMSTAT comstat;改成static COMSTAT comstat;就能編譯成功而且發送接收消息正常。其實,在Release下,它的基本運行時檢查初始設置已爲默認。這應該也算是第一種解決方案以內。
而當你將它設置爲二者(/RTC1,等同於 /RTCsu)時,不管是否將COMSTAT comstat;改成static COMSTAT comstat;,編譯都不能經過,報錯「「cl.exe」返回的結果有誤。",這個應該是屬於Release的問題了,另當別論了。
三、C++鏈接MYSQL
1)、新建一個工程,隨便寫一個helloworld,目的是就是讓工程下的「debug」文件夾出現
2)、把D:\Program Files\MySQL\MySQL Server 5.5\lib下面的libmysql.dll複製到工程的debug文件夾裏面
3)、接下來要設置一些引用文件的環境變量,首先,點擊項目->屬性->vc++目錄。
而後「include目錄」那把「D:\Program Files\MySQL\MySQL Server 5.5\include」給加進來
再而後「lib目錄」那裏把「D:\Program Files\MySQL\MySQL Server 5.5\lib」也一塊兒加進來
VC6.0設置:
(1)打開VC6.0 工具欄Tools菜單下的Options選項,在Directories的標籤頁中右邊的「Show directories for:」下拉列表中選中「Includefiles」,而後在中間列表框中添加你本地安裝MySQL的include目錄路徑。(個人是D:\Program Files\MySQL\MySQL Server 5.5\include)。
(2)在上面說到的「Show directories for:」下拉列表中選中「Library files」,而後添加你本地安裝MySQL的Lib目錄路徑。Lib目錄下有debug目錄,選debug。(個人是D:\Program Files\MySQL\MySQL Server 5.5\lib\debug)。
4)、而後在項目->屬性窗口下點擊:鏈接器->輸入->附加依賴項,把"libmysql.lib"寫進去
VC6.0設置:在「Project settings->Link:Object/library modules」裏面添加「libmysql.lib」。
使用VC++編譯時再添加如下項:
5)、在stdafx.h裏面添加以下的內容:
#include "mysql.h"
#include "winsock.h" // 若是編譯出錯,則把該行放到#include "mysql.h"以前#pragma comment(lib,"libmySQL.lib") // 若是在附加依賴項裏已增長,則就不要添加了
3.1
1>test.obj : error LNK2019: 沒法解析的外部符號 _mysql_close@4,該符號在函數 _main 中被引用
1>test.obj : error LNK2019: 沒法解析的外部符號 _mysql_fetch_row@4,該符號在函數 _main 中被引用
1>test.obj : error LNK2019: 沒法解析的外部符號 _mysql_store_result@4,該符號在函數 _main 中被引用
1>test.obj : error LNK2019: 沒法解析的外部符號 _mysql_query@8 ,該符號在函數 _main 中被引用
1>test.obj : error LNK2019: 沒法解析的外部符號 _mysql_real_connect@32,該符號在函數 _main 中被引用
1>test.obj : error LNK2019: 沒法解析的外部符號 _mysql_options@12 ,該符號在函數 _main 中被引用
1>test.obj : error LNK2019: 沒法解析的外部符號 _mysql_init@4,該符號在函數 _main 中被引用
1>D:\Program_Files\C&C++\test_mysql\Debug\test_mysql.exe : fatal error LNK1120: 7 個沒法解析的外部命令
此異常是沒有在項目屬性的鏈接器中的「附加依賴項」中添加libmysql.dll。
3.2 編譯正常,運行的時候報錯:沒法啓動此程序,由於計算機中丟失libmysql.dll。嘗試從新安裝該程序解決此問題。
此問題是由於沒有將解壓後的mysql目錄下lib/debug(opt)中的libmysql.dll拷貝到工程目錄下(或debug目錄中)。
3.3
1>c:\program files\mysql\mysql server 5.5\include\mysql_com.h(291): error C2146: 語法錯誤: 缺乏「;」(在標識符「fd」的前面)
1>c:\program files\mysql\mysql server 5.5\include\mysql_com.h(291): error C4430: 缺乏類型說明符 - 假定爲 int。注意: C++ 不支持默認 int
1>c:\program files\mysql\mysql server 5.5\include\mysql_com.h(291): error C4430: 缺乏類型說明符 - 假定爲 int。注意: C++ 不支持默認 int
1>c:\program files\mysql\mysql server 5.5\include\mysql_com.h(470): error C2065: 「SOCKET」: 未聲明的標識符
1>c:\program files\mysql\mysql server 5.5\include\mysql_com.h(470): error C2146: 語法錯誤: 缺乏「)」(在標識符「s」的前面)
1>c:\program files\mysql\mysql server 5.5\include\mysql_com.h(471): error C2059: 語法錯誤:「)」
上述錯誤緣由要結合編譯環境來解決。
1)windows.h頭文件必須放在mysql.h以前;
2)在VS2008中,若已經執行了第一步卻仍然不行,檢查mysql.h以前是否有以下代碼:
#define WIN32_LEAN_AND_MEAN // 從 Windows 頭中排除極少使用的資料
上述語句一般在stdafx.h中。刪掉該句便可。
3.4
>正在連接...
1>stdafx.obj : error LNK2005: "public: struct st_mysql_res * __thiscall DBUtil::ResultSet(char *)" (?ResultSet@DBUtil@@QAEPAUst_mysql_res@@PAD @Z ) 已經在 PreThread.obj 中定義
1>stdafx.obj : error LNK2005: "public: __thiscall DBUtil::~DBUtil(void)" (??1DBUtil@@QAE@XZ ) 已經在 PreThread.obj 中定義
1>stdafx.obj : error LNK2005: "public: void __thiscall DBUtil::Init(void)" (?Init@DBUtil@@QAEXXZ) 已經在 PreThread.obj 中定義
1>stdafx.obj : error LNK2005: "public: __thiscall DBUtil::DBUtil(char *,char *,char *,char *)" (??0DBUtil@@QAE@PAD000@Z ) 已經在 PreThread.obj 中定義
1>stdafx.obj : error LNK2005: "public: __thiscall DBUtil::DBUtil(void)" (??0DBUtil@@QAE@XZ ) 已經在 PreThread.obj 中定義
1>D:\Program_Files\Multi-Core\XOJ_ACS\Release\XOJ_ACS.exe : fatal error LNK1169: 找到一個或多個多重定義的符號
頭文件被重複包含
4.「MessageBoxW」: 不能將參數 2 從「const char [1]」轉換爲「LPCWSTR」
(部分摘自:http://topic.csdn.net/u/20080412/19/89EFF60A-C2C0-492F-BC04-FC68B3B5B6FB.html)
由於你的程序在UNICODE(寬字節)字符集下運行,若是調用了 MessageBox ,實際上調用的是 MessageBoxW 函數;
若是你的程序在 ANSI 字符集運行,調用 MessageBox ,就至關於調用 MessageBoxA;
其中 MessageBoxW 支持 UNICODE;
MessageBoxA 支持ANSI;
UNICODE與ANSI 有什麼區別呢?簡單的說,UNICODE版的字符比ANSI 的內存佔用大,好比:
Win32程式中出現的標準定義 char 佔一個字節,
而 char 的UNICODE版被定義成這樣:
typedef unsigned short wchar_t ;佔2個字節。
因此有字符作參數的函數相應也用兩個版本了。
寬字節版函數中帶有字符參數的都應該用寬字節版的字符參數,將字符串轉換成寬字節很容易:
好比將 "Application Error" 轉換成UNICODE版,只需在它前面使用一個定義了的宏,以下:
L"Application Error" ,或者TEXT("Application Error" )均可以
因此你應將 MessageBox(NULL,Temp,"Application Error",MB_ICONSTOP); 改成:
MessageBox(NULL,Temp,L"Application Error",MB_ICONSTOP);
五、fatal error LNK1107: 文件無效或損壞: 沒法在 0x278 處讀取
該問題多是引入的庫不正確,可是通過查看,引入的文件以及庫均正確,僅僅是刪除了項目屬性,鏈接器中的「附加依賴項」中的值,本項試試刪除該項是否會致使程序沒法運行,結果顯示這個錯誤。等再次加上的時候,依然無效,索性將全部引入的文件以及庫均刪除,所有從新添加,問題解決。
六、 編譯正常,運行的時候報錯:"0x0041596d" 指令引用的"0x00000000"內存。該內存不能爲"written"。
錯誤緣由:這是指針結構沒初始化,而引用產生的地址錯誤
以下:
char *hostname = "localhost";
char *username = "root";
char *pass = "111";//你的mysql服務器密碼
char *dbname = "mysql";
unsigned int port = 3306; //server port
struct Database_Param *mysql_param;//沒有初始化就引用了
struct Data_Param *db_param; //沒有初始化就引用了
int main()
{
CDatabase MySqldb;
mysql_param->host = hostname;
mysql_param->user = username;
mysql_param->password =pass;
mysql_param->db = dbname;
mysql_param->port = 3306;
//mysql_param->unix_socket,NULL;
mysql_param->client_flag = 0;
//mysql_param = &db_param;
db_param->db_name = mysql_param->db;
修改後:
char *hostname = "localhost";
char *username = "root";
char *pass = "111";//你的mysql服務器密碼
char *dbname = "mysql";
unsigned int port = 3306; //server port
struct Database_Param *mysql_param;
struct Data_Param *db_param;
int main()
{
CDatabase MySqldb;
mysql_param = new (struct Database_Param );//對指針先初始化後引用
db_param = new (struct Data_Param);
mysql_param->host = hostname;
mysql_param->user = username;
mysql_param->password =pass;
mysql_param->db = dbname;
mysql_param->port = 3306;
//mysql_param->unix_socket,NULL;
mysql_param->client_flag = 0;
//mysql_param = &db_param;
db_param->db_name = mysql_param->db;
七、error C2593: 「operator +=」不明確
處理串口輸入事件時
afx_msg LRESULT CSerialPortptestDlg::OnComm(WPARAM wParam, LPARAM lParam)
{
m_strEditReceiveMsg += wParam;
UpdateData(FALSE); //將接收到的字符顯示在接收編輯框中
return 0;
return 0;
}
編譯時出現「operator +=」不明確,也就是m_strEditReceiveMsg += wParam;
改正方法:
m_strEditReceiveMsg += (char)wParam;,由於系統裏面存在一個wchar_t的類型,因此若是支持了這個類型的話,從unsigned nt轉換到wchar_t和char的等級都是標準轉換,因此編譯器沒法判斷到底應該轉換到哪個,故而致使了這個問題。
1>i:\prj\commterm\commterm\serial\serialport.cpp(23): error C2664: 「CreateFileW」: 不能將參數 1 從「const char *」轉換爲「LPCWSTR」
1> 與指向的類型無關;轉換要求 reinterpret_cast、C 樣式轉換或函數樣式轉換
點擊項目->屬性->配置屬性->常規
而後「字符集」那把「使用 Unicode 字符集」改成「未設置」或「使用多字節字符集」
再而後「lib目錄」那裏把「D:\Program Files\MySQL\MySQL Server 5.5\lib」也一塊兒加進來
#include "stdafx.h"
#include <winsvc.h>
若是顛倒了,就會出現下面一堆使人頭疼的錯誤:
正在編譯...
ServerTest.cpp
e:\Project C++\ServerTest\ServerTest\ServerTest\ServerTest.cpp(58) : error C2146: 語法錯誤 : 缺乏「;」(在標識符「hServStatus」的前面)
e:\Project C++\ServerTest\ServerTest\ServerTest\ServerTest.cpp(58) : error C2501: 「hServStatus」 : 缺乏存儲類或類型說明符
e:\Project C++\ServerTest\ServerTest\ServerTest\ServerTest.cpp(59) : error C2146: 語法錯誤 : 缺乏「;」(在標識符「hSStat」的前面)
e:\Project C++\ServerTest\ServerTest\ServerTest\ServerTest.cpp(59) : error C2501: 「hSStat」 : 缺乏存儲類或類型說明符
e:\Project C++\ServerTest\ServerTest\ServerTest\ServerTest.cpp(75) : error C2065: 「SERVICE_TABLE_ENTRY」 : 未聲明的標識符
e:\Project C++\ServerTest\ServerTest\ServerTest\ServerTest.cpp(75) : error C2146: 語法錯誤 : 缺乏「;」(在標識符「DispatchTable」的前面)
在控制檯下寫程序
控制檯下用windows API寫比較好。用這個類型:CRITICAL_SECTION g_cs;
而後 InitializeCriticalSection(...)
EnterCriticalSection(...);
LeaveCriticalSection(...);
CRITICAL_SECTION m_sec; InitializeCriticalSection( &m_sec ); DeleteCriticalSection( &m_sec ); EnterCriticalSection( &m_sec ); LeaveCriticalSection( &m_sec );