_dupenv_s()のマイラッパー関数

やあ子供たち。
 getenv()はC言語において環境変数を取得するための便利な手法でしたが、VisualStudio2013ExpressEditionとかではもはやwarningではなくerrorとして扱われるようになってしまいました。たしかに、getenv()は文字列を返す関数ですが、よくよく考えてみればこれメモリ管理どうなってるんだという疑問とか、謎なところはありましたよね。というわけでその代りこれ使えとコンパイラが言ってきているのが、
_dupenv_s()という、getenvとはおよそ似ても似つかない関数名と仕様を持った、未知との遭遇型のAPIだったのです。
 しかもこの_dupenv_s()、

  1. ダミー引数を含め引数が増えていたり、返り値の意味も独特なため、使うたびに説明を見に行くはめに絶対なりそう。
  2. 環境変数の内容の格納領域を明示的に確保するようになったのはいいが、その解放はユーザー任せ。(忘れたら大変!)
  3. モリーが確保できなかった場合のエラーなどが帰る仕様になっているが、よっぽど組み込みとかでもない限りgetenv相当の動作に必要となるメモリ確保が問題になることはまずなかろう

といった多岐にわたる議論や理由や楽天的な個人的見解から、えいやっという感じのラッパー関数を作成しましたので以下に紹介します。

#include <windows.h>

static bool dupenv_my_wrapper(const char* env, string* val)
{
	// 環境変数"env"の取得に…
	//  失敗した場合→返り値=false
	//  成功した場合→返り値=true, 環境変数の内容をvalに。
	char* buf = 0;
	size_t sz = 0;
	if (_dupenv_s(&buf, &sz, env) == 0)
	{
		if (!buf)
		{
			// 環境変数は定義されていなかった場合。
			return 0;
		}
		// 環境変数が定義されていた場合。
		*val = buf;
		free(buf);
	}
	else
	{
		// 環境変数云々以前に、結果格納用の
		// メモリ空間取得などで問題発生した場合。
		return 0;
	}
	return !0;
}

使い方の例は以下の通りです。

string vshPath;
const char vshEnv[] = "DEFAULT_VSHPATH";
if (!dupenv_my_wrapper(vshEnv, &vshPath))
{
	::MessageBox(0, vshEnv, "env not found", MB_OK);
	return;
}

要はメモリ管理の問題をstd::stringに託してしまえ!という作戦です。
環境変数あった?ない?を、返り値で確認し、あった場合はその内容を、stringにつめて返してくれます。
それだけのシンプル動作。
あくまで個人的にですが当面は以上が、getenv()を使いたくなったときの新しい代替え手法となりそうです。