2012-03-13 16 views
1

固定長の文字列を解析するプログラムを開発しようとしています。不正な整数値の整列

私自身のパーサークラスを書く代わりに、マーシャリングを使用することに決めました。下のように私は構造体を定義しました:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
public struct MyStruct 
{ 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)] 
    public string Name;    

    [MarshalAs(UnmanagedType.I4, SizeConst = 2)] 
    public int Age;    

} 

私はこの構造体をこのように呼びます。

string message = "SampleName30"; 
IntPtr pBuf = Marshal.StringToBSTR(message); 
MyStruct ms = (MyStruct)Marshal.PtrToStructure(pBuf, typeof(MyStruct)); 

私は値をチェックした場合:

ms.Name is SampleName // OK 

しかしms.Age値は3145779を返します。私は期待していますms.Age = 30

何が間違っていますか?この問題を解決するにはどうすればよいですか?

+0

ここでマーシャリングを使用するのはかなり悪い考えです... –

+0

UnamangedType.I4では使用しないでくださいが、なぜSizeConstを使用していますか?配列や文字列ではありません。アンマネージ構造定義を転記できますか? –

+0

私の目的は、最後の2文字を年齢として設定することです。だから私は構造についてのsizeconstを与える。 – enduser237

答えて

2

これは非常に大きな混乱です。

最初のものが最初です。 3145779は16進数で300033です。 '3'は16進数で33、 '0'は16進数で30、ユニコードとエンディアンを加えて300033になります(これは本当にここでは問題にならないので、私はこれを正確に再現しませんでした)。

このように文字列を数値に変換できない場合は、それをデコードする必要があります。各桁の文字をその数値に変換します。

なぜこのように文字列を解析しようとしていますか?あなたは、インターフェイスが少し整然とするべき

struct MyStruct 
{ 
    public string Name; 
    public int Age; 

    public static MyStruct ParseString(string s) 
    { 
     var my = new MyStruct(); 

     Name = s.substring(0, 10); 
     Age = int.Parse(s.substring(11)) 
    } 
} 

、およびエラー(短いまたは長い文字列の世話をする、(代わりに、Parseメソッドのコンストラクタのプロパティ?):それは、このコードを使用することをお勧めし永劫ではありません無効な整数)ですが、それはジストです。

+1

+1優れた答え! – gideon

+0

私は受け入れ率に取り組んでいます - 受け入れられる回答の数:-) – zmbq

0

理由は、文字列が"30"であり、整数ではない30であるためです。ユニコード文字列"30"のバイナリ表現は、数字3145779のバイナリ表現と同じです。

マーシャリングを使用するのではなく、独自のパーサーを作成することをお勧めします。

+0

私はあまりにも多くの構造体を持っています。だからこの方法はとても簡単です。私は文字列の長さをstruct属性に1つだけ書きます。マーシャルはそれを自動的に解析して長さを与えます。 私は文字列として "年齢"を得ることができますが、数値数値をチェックしたいですか?私にとってこれらの情報を十分に入手してください。 値は数値か、例外を送信できますか? – enduser237