【TLC の Tech Blog 復刻版】API 呼出し後に String が切れる
API呼び出しの引数として文字列(String型変数)を渡す場合。
渡す文字列値に2バイト文字が混じっていると,引き渡した変数の値の後方の何文字かが切り落とされてしまう。という現象が発生しています。
API GetPrivateProfileStringのlpFileNameの例
Result=GetPrivateProfileString(section, _
key, _
default, _
valuebuffer, _
length, _
iniFileString)
とした場合に,API宣言がByValとしていても
iniFileStringに2バイト文字を含むパスが設定されている場合,API呼出し後のiniFileStringの値は途中で途切れたものに変更されてしまいます。
つまり,変数に"c:\一時ファイル\temp.ini"などと渡すと
API呼出し後に"C:\一時ファイル\t"などと後半部分の一部がきれた値に書き換えられてしまいます。
これは,VB の String がAPIに渡されるために,起こっているようです。
とりあえず,引き渡す文字列をそのまま渡さずに,ToCharArrayメソッドを介してコピー渡しをすると回避できます。
lpFileName.ToCharArrayなどとして渡します。
また,もっと根本的な解決として,
引数を渡す際に()でくくって渡すと,明示的に値渡しをすることができます。
Result=GetPrivateProfileString(section, _
key, _
default, _
valuebuffer, _
length, _
(iniFileString))
と呼び出すことで,変数が書き換えられてしまうことを防止できます。
これらは VB 側の変数の値を書き換えられないようにしているだけです。
さて,ここで C について考えてみましょう。
C の文字列は終端に Null 文字をつけることによって文字列の終端を認識していますよね。
じゃー,つけてあげればいいのでは?
iniFileString = String.Concat(iniFileString,ControlChars.NullChar)
これできれいに文字切れが起こらなくなります。
どれでも回避できますが,みなさんどれがお好みですか?