TimberLandChapelのTech Blog

TimberLandChapel が提供する技術Tips,思いつきメモ,雑感ブログです。
Office 互換リボン Release 1.0 をリリースしました。

購読

Books

INETAJ

Microsoft

SQL Server

TLC.com

クリエイティブ・コモンズ

情報処理関係官公庁

今期のアンケート

【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)

これできれいに文字切れが起こらなくなります。

どれでも回避できますが,みなさんどれがお好みですか?

Published 2005年9月27日 12:35 投稿者 timberlandchapel

コメント

コメントはありません