無法解析的外部符號 _ ,該符號在函數 " __main中被引用 && This function or variable may be unsafe.


加上winsock2的運行庫看看吧,一般不用加的啊

#pragma comment(lib,"Ws2_32.lib")

應該就沒有問題了吧^_^

 

 

以下為轉載  

http://blog.chinaunix.net/uid-20672257-id-2955771.html

 

1、將過去的工程用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 
那么如何搞定這些警告呢:

原因解釋
這種微軟的警告,主要因為那些C庫的函數,很多函數內部是不進行參數檢測的(包括越界類的),微軟擔心使用這些會造成內存異常,所以就改寫了同樣功能的函數,改寫了的函數進行了參數的檢測,使用這些新的函數會更安全和便捷。關於這些改寫的函數你不用專門去記憶,因為編譯器對於每個函數在給出警告時,都會告訴你相應的安全函數,查看警告信息就可以獲知,在使用時也再查看一下MSDN詳細了解。庫函數改寫例子:
mkdir改寫為 _mkdir 
fopen”改寫為 fopen_s 
stricmp改寫為 stricmp_s
sprintf改寫為sprintf_s

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。 
注意:這個方法雖然使用了新的函數,但是不能消除警告你還得同時使用方法二。。。

2、SerialPort收數據時出現的BUGcomstat is being used without defining

比如: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解釋“為重載運算符定 
義了多個可能的運算符。可能的解決方案:對一個或多個實際參數使用顯式轉換。”當將

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應用中的問題了。那該如何解決這個問題呢?在這,我們向大家提供兩種解決方案:

方案1: 改變項目配置屬性

    一種解決方案是改變基本運行時檢查(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的問題了,另當別論了。

3、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);

5、fatal error LNK1107: 文件無效或損壞: 無法在 0x278 處讀取

該問題可能是引入的庫不正確,但是經過查看,引入的文件以及庫均正確,僅僅是刪除了項目屬性,連接器中的“附加依賴項”中的值,本項試試刪除該項是否會導致程序無法運行,結果顯示這個錯誤。等再次加上的時候,依然無效,索性將所有引入的文件以及庫均刪除,全部重新添加,問題解決。

6、 編譯正常,運行的時候報錯:"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;

7、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 );
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM