wchar_t類型的實質

VC++編譯器中包括一種本機類型,用來支持長字符串,它就是wchar_t,它所佔用的內存長度爲2個字節,同時VC++編譯器2個字節長度的類型有short, unsigned short。(參考鏈接:http://msdn.microsoft.com/zh-cn/library/dh8che7s(VS.80).aspx)它們相互之間其實是可以進行類型轉換而不會發生內存定位錯誤的,如:

 

(在打開編譯器選項/Zc:wchar_t的情況下)

#include "stdafx.h"
#include <windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
 unsigned short *pUShort ;  //或是 short *pUShort;

 wchar_t *pWChar = L"ABCD";

 pUShort = (unsigned short*)pWChar;

 MessageBoxW(NULL,(wchar_t*)pUShort, L"ok", 0); //OK,這樣是可以的

    return 0;
}

所以,VC++對wchar_t提供了兩種實現方式,

1.以unsinged char 來做爲wchar_t來處理:typedef unsigned char wchar_t ;

2.直接提供wchar_t的本機類型。它由加入/Zc:wchar_t編譯器選項來實現。

 

爲什麼要這樣做?

 

它可能是與在X386平臺下的int和long類型的關係一樣,它們的內存空間長度是相同的,但明顯long這個名稱可以給人一種直觀的認識。


那麼這個編譯器選項到底做了什麼呢?

 

如下函數:

public: virtual long __stdcall CBaseFilter::QueryVendorInfo(wchar_t * *)

在沒有加入/Zc:wchar_t編譯器選項時,編譯器輸出的函數符號爲:

?QueryVendorInfo@CBaseFilter@@UAGJPAPAG@Z

但在加入此選項之後,編譯器輸出的函數符號爲:

?QueryVendorInfo@CBaseFilter@@UAGJPAPA_W@Z

看到了嗎?最後的一個字符是不同的,G(未加選項)_W(加選項)

 

所以它們的最終輸出的函數符號是不同的,這樣的話,會發生某些情況:

 

如果生成了一個靜態或是動態庫,它使用unsigned char來實現wchar_t類型,而調用它的程序以本機類型方式來實現wchar_t類型,則在鏈接調用程序時,會發生“unresolved external symbol ”(“無法解析的外部符號”)錯誤。所以在使用wchar_t類型時一定要注意多個工程相互調用時,要將wchar_t的實現方式設置爲相同的。

 

實際工作中,可能會經常出現的由此原因所產生的錯誤:

directshow所提供的BaseClasses工程就默認將wchar_t設置爲由unsigned short來實現,如果由MFC程序來實現一個direct show工程的話,因爲MFC工程默認將提供wchar_t本機類型。所以如果直接編譯的話,在最後的鏈接過程之中就會發生以下的鏈接錯誤:


MP4MiscRenderer.obj : error LNK2001: 無法解析的外部符號 "public: virtual long __stdcall CBaseFilter::QueryVendorInfo(wchar_t * *)" (?QueryVendorInfo@CBaseFilter@@UAGJPAPA_W@Z)
MP4MiscRenderer.obj : error LNK2001: 無法解析的外部符號 "public: virtual long __stdcall CBaseFilter::JoinFilterGraph(struct IFilterGraph *,wchar_t const *)" (?JoinFilterGraph@CBaseFilter@@UAGJPAUIFilterGraph@@PB_W@Z)
MP4MiscRenderer.obj : error LNK2001: 無法解析的外部符號 "public: virtual long __stdcall CBaseRenderer::FindPin(wchar_t const *,struct IPin * *)" (?FindPin@CBaseRenderer@@UAGJPB_WPAPAUIPin@@@Z)

 

這是一個很不明顯的錯誤,單從源代碼的角度來看,是無法找出錯誤的位置的。

發佈了36 篇原創文章 · 獲贊 2 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章