2012-07-19 77 views
3

我有以下非託管結構。元帥非0終止字符串

struct MyNativeStruct_Foo 
{ 
char product_name[4]; 
char product_model[2]; 
} 

和託管相當於

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
public struct MyManagedStruct_Foo 
{ 
    [MarshalAs(UnmanagedType.LPStr, SizeConst = 4)] 
    public string product_name; 

    [MarshalAs(UnmanagedType.LPStr, SizeConst = 2)] 
    public string product_model; 
} 

不幸的是,刺不空終止。使用產品名稱的所有4個字符。如果我使用「LPStr」定義託管結構,則字符串必須以0結尾。

是否有另一種方法來定義託管結構?可以定義一個自定義的Marshaller屬性?或者你有其他想法?

注意; 本機結構無法更改。

感謝

安貝格

[編輯] 改爲LPSTR(評論賈森Larke)

+1

請注意,您的C++聲明使用'char'而不是'char_t',所以您的聲明不應該需要'TStr'。另外,你明確地將結構的CharSet設置爲'ANSI' :) – 2012-07-19 08:33:00

回答

4

你可以改變編組處理字符串作爲一個固定大小的數組的bytes秒,然後使用Encoding類將字節轉換爲受管字符串。

[StructLayout(LayoutKind.Sequential)] 
public struct MyManagedStruct_Foo 
{ 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=4)] 
    public byte[] product_name; 

    [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)] 
    public byte[] product_model; 

    public string GetProductName() 
    { 
     return System.Text.Encoding.ASCII.GetString(this.product_name); 
    } 

    public string GetProductModel() 
    { 
     return System.Text.Encoding.ASCII.GetString(this.product_model); 
    } 
} 

不完全是世界上最性感的結構,但它應該是罰款您的需求。

+0

我對自定義編組器和自定義Marshaller屬性做了一些嘗試,因爲這些字符串通常在不同的結構中。但我有問題將字符串長度傳遞給自定義Marshaller。 您的解決方案將產生更多的代碼行,但效果很好。謝謝 – 2012-07-19 09:05:26

+0

我從來沒有嘗試過從非託管內存編組固定長度的字符串,這就是爲什麼我發佈了一個簡單的'字節'解決方案。如果我今晚得到時間,我會試着弄清楚這個結構,看看我能否以更好的方式完成它。 – 2012-07-19 09:24:34