私はUnicode文字列をサポートしていないマルチバイトANSI文字列をサポートしているライブラリ用のPInvokeラッパーを開発中です。ライブラリのFxCopレポートを調べているうちに、使用されている文字列マーシャリングには面白い副作用があることに気付きました。 PInvokeメソッドは、「最適な」マッピングを使用してシングルバイトのANSI文字列を作成していました。非ASCII文字を含む文字列で、この関数を呼び出した結果は、Windowsがそれが終わるように、一般的にこれが見え、「クローズ」の文字を見つけたということですマルチバイトのANSI文字列を入力するにはどうすればよいですか?
[DllImport("thedll.dll", CharSet=CharSet.Ansi)]
public static extern int CreateNewResource(string resourceName);
:説明のため、これは一つの方法は次のように見えたものですであること "???"。 'a'が非ASCII文字であると仮定すると、 "cat"をパラメータとして渡すと、 "c?t"という名前のリソースが作成されます。
私はFxCopのルールのガイドラインに従った場合、私はこのようなもので終わる:
[DllImport("thedll.dll", CharSet=CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
public static extern int CreateNewResource([MarshalAs(UnmanagedType.LPStr)] string resourceName);
これは、動作の変更が導入されました。現在、文字をマップできないと例外がスローされます。これは私にとって心配です。これは大きな変化であるため、文字列を複数バイトのANSIとしてマーシャリングしたいと思いますが、その方法はわかりません。 UnmanagedType.LPStr
は1バイトのANSI文字列、LPTStr will be Unicode or ANSI depending on the system, and LPWStr is not what the library expects.
How would I tell PInvoke to marshal the string as a multibyte string? I see there's a
これには、現在の実装にはまだ多くの問題があります(文字を削除または置換する必要があるかもしれません)ので、これが改善かどうかはわかりません。私が行方不明にしているマーシャルのもう一つの方法はありますか?WideCharToMultiByte()
API関数に指定されていますが、アンマネージドメモリに作成する文字列にIntPtrがあると予想するように署名を変更することはできますか?
あなたが正しいと思います。私は現在のコードページの外で文字の方法でテストしていて、コードページで実際に動作するマルチバイト文字を考えることができませんでした。私はいくつかの自信を得るために関数に投げることのできるコードページと文字の組み合わせを見つけようとしていますが、あなたが正しいと思います。 – OwenP
私はそれをテストする方法を理解しました:私は持っている日本語ローカライズされたXP用のイメージを使用し、多くの日本語文字で構成された名前でリソースを設定しました。これは日本のマシンではうまくいったが、英語マシンでは悲惨に失敗した。 私はUnicodeを使用しているかのように動作するようにしたいと思いますが、あなたの説明と実験から、これは不可能であるとわかります。私は、ライブラリのメンテナーがUnicodeサポートを実装するのを待たなければなりません。 – OwenP