PInvoke と文字コード

次のような2つのメソッドを考える。

[DllImport("test.dll", CharSet=CharSet.Auto)]
extern void Test1(string msg);

[DllImport("test.dll", CharSet=CharSet.Auto)]
extern void Test2(IntPtr buffer, int size);

前者には小さな問題はあるが大きな問題はない。
test.dll が Ansi 用のエントリポイントしか提供しなければ、引数 msg は現在スレッドのカルチャと OS の文字セットに従った ANSI コードにマーシャリングされるし、Unicode 用のエントリポイントを持っていれば文字コードの変換なしに、いわゆる C-String としてポインタだけが渡される。
問題は、以前、GDNJ の掲示板でも書いたが、後者の buffer に対して文字列を渡したい場合である。
IntPtr 型の変数に適切にメモリを割り当て、手動でエンコードをあわせてマーシャリングする……それだけのことなのだが、Test2 が test.dll において Ansi 用のエントリポイントに解決されたのか、Unicode 用のエントリポイントに解決されたのか、判断する手段がない。
Marshal クラスには、明示的に Ansi/Unicode を指定しない StringToHGlobalAuto() や StringToCoTaskMemAuto() というメソッドがあるが、こいつらには何も期待できない。
こいつらは、あらかじめ Marshal クラスが初期化されたときに決定*1された Ansi/Unicode の種別を用いて、同Ansi() および 同Unicode() を呼び分けるだけである。

*1:この判断は lstrlen API を用いて行われるため、lstrlenW が提供される環境では Unicode と判定されるようになっているようだ