2012-12-19 17 views
1

此問題特定於Visual C++(您可能會假定Visual C++ 2005及更高版本)。有沒有一種方法可以在宏內部有條件地使用_T/TEXT?

我想爲unixoid系統(特別是FreeBSD)的程序創建膠水代碼,以在Win32上構建和運行,並對原始文件.c進行最小的更改。現在,大部分都很簡單,但現在我遇到了一個問題。我正在使用tchar.h標題和TCHAR/_TCHAR,並且需要爲原始代碼中的errerrx調用(請參閱err(3))創建粘合代碼。即使您不同意使用tchar.h的代碼仍然應該寫入,我也要忍受。

errerrx的調用採取大致有兩種形式,這就是問題出現時:

err(1, "some string with %d format specifiers and %s such", ...) 
/* or */ 
err(1, NULL, ...) 

後者將輸出存儲在errno誤差(使用strerror)。

現在,問題是,有沒有辦法編寫一個通用的宏,可以採取NULL和字符串文字?我不需要(和不會)關心變量作爲第二個參數傳遞,只有NULL和文字字符串。

當然,我的天真最初的方法沒有考慮fmt作爲NULL傳遞(使用複雜的宏!):

#define err(eval, fmt, ...) my_err(eval, _T(fmt), __VA_ARGS__) 

現在我沒有任何想法如何用宏來實現這一點,因爲它需要一種我目前無法想象的編譯時和運行時條件的混合。所以我正在尋找一個權威的答案,究竟這是否可以想像。

的方法,我訴諸現在 - 缺乏一個更好的方法 - 就是如果與定義_UNICODE彙編編寫一個接受的包裝功能,就像errerrx,一個(constchar *,然後轉換,爲wchar_t *。這應該可以,假設調用者在fmt(這是我的上下文中的一個理智的假設)之後爲可變參數傳遞了_TCHAR*字符串。否則,我還必須在格式字符串中將%s轉換爲%hs,以便在MS調用它們時處理「ANSI」字符串。

+0

FWIW,你可以通過使用直接的#define用於犯錯,如果沒有定義_UNICODE,只包括包裝函數如果稍微提高的問題。 –

回答

1

這裏有一個解決方案:

#define _WIN32_WINNT 0x0502 

#include <windows.h> 
#include <stdio.h> 
#include <tchar.h> 

#ifdef _UNICODE 

#define LNULL NULL 
#define fn(x) myfn(L ## x) 

#else 

#define fn(x) myfn(x) 

#endif 

void myfn(TCHAR * str) 
{ 
    if (str == NULL) _tprintf(_T("<NULL>")); else _tprintf(str); 
    _tprintf(_T("\n")); 
} 

int main(int argc, char ** argv) 
{ 
    fn("hello"); 
    fn(NULL); 
    return 0; 
} 
+0

這是一個聰明的方法。謝謝! – 0xC0000022L

相關問題