TimberLandChapel's Tech Blog

TimberLandChapel provide Tips, tech note and scribbling.
Updated my site as English site for APAC users.
TLC.com .Metrix 4.0 Beta1 released

サイトの日本語化方法はこちら

Syndication

News

INETAJ

情報処理関係官公庁

SQL Server

TLC.com

Microsoft

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

http://www3.clustrmaps.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 by timberlandchapel

Comments

No Comments