元帅非0终止字符串

问题描述:

我有以下非托管结构。元帅非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

你可以改变编组处理字符串作为一个固定大小的数组的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