1

この質問は、Visual C ++に固有のものです(Visual C ++ 2005以降を想定している場合があります)。

元のファイルへの変更を最小限に抑えてWin32でビルドおよび実行するために、unixoidシステム(特にFreeBSD)からプログラムのグルーコードを作成したいと思い.cます。さて、これのほとんどは簡単ですが、今私は問題に遭遇しました。tchar.hヘッダーとTCHAR/を使用しており、元のコードでと呼び出し(を参照)_TCHARのグルーコードを作成する必要があります。使用するコードを作成することに同意しない場合でも、我慢してください。errerrxerr(3)tchar.h

の呼び出しerrerrxはおおよそ2つの形式を取ります。ここで、問題が発生します。

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

後者は、errno(を使用してstrerror)に格納されているエラーを出力します。

さて、問題は、文字列リテラルと文字列リテラルの両方を取ることができるジェネリックマクロを書く方法はありますNULLか?変数が2番目のパラメーターとして渡されることを気にする必要はありません(そして気にしません) 。リテラル文字列のみです。NULL

もちろん、私の素朴な最初のアプローチは、 (可変個引数マクロを使用して!)fmtとして渡されたものを考慮していませんでした:NULL

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

今のところ、マクロを使用してこれを実現する方法はわかりません。これは、現時点では想像できないようなコンパイル時と実行時の条件の組み合わせが必要になるためです。ですから、これが考えられるかどうかにかかわらず、信頼できる答えを探しています。

私が今頼っている方法(より良いアプローチがない)は、andと同じようerrerrxconst)を受け入れるラッパー関数を記述し、それをdefinedでコンパイルされchar *た場合に変換することです。これは、呼び出し元が(私のコンテキストでは正しい仮定です)の後に変数引数の文字列を渡すと仮定すると、機能するはずです。それ以外の場合は、MSが呼び出すように、「ANSI」文字列を処理するために、フォーマット文字列内に変換する必要があります。wchar_t *_UNICODE_TCHAR*fmt%s%hs

4

1 に答える 1

1

ここに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;
}
于 2012-12-21T02:09:44.543 に答える