C#错误:无法使用包含在未固定表达式中的固定大小缓冲区

本文关键字:表达式 缓冲区 错误 包含 | 更新日期: 2023-09-27 18:00:52

我正在使用C#程序从数据库中读取二进制记录。这些记录是由Borland Delphi创造的。这里有一个例子:

//Delphi记录定义tBowler_Rec=记录平民的gender:t性别;bowler_num:字节;name:tString32;首字母缩写:String[3];…
//对应的C#定义(非托管代码([结构布局(LayoutKind.Sequential,Pack=4(]公共不安全结构tBowler_Rec{公共t性别;公共字节bowler_num;公共固定字节名称[32];公共固定字节首字母[3];…

实际上,我能够从SQL Server数据库中读取这个二进制结构,并在Visual Studio调试器中查看数据。耶!我能够访问诸如";性别";以及";bowler_num";没有问题。耶!

Q: 我该如何转动";name";转换成C#字符串?

一个示例名称是";阿什顿";。在内存中看起来是这样的:

''0x6ASHTON''0x0''0x0…

以下是我尝试访问它的方式:


[StructLayout(LayoutKind.Sequential, Pack=4)]
public unsafe struct tBowler_Rec
{
    public tGender gender;
    public byte bowler_num;
    public fixed byte name[32];
    ...
    public string Name
    {
        get
        {
            StringBuilder sb = new StringBuilder();
            int ilen = name[0];
            for (int i = 1; i <= ilen; i++)
                sb.Append(name[i]);
            return sb.ToString();
        }
    }

我得到这个错误:

错误:不能使用包含在未固定缓冲区中的固定大小缓冲区表达式。尝试使用fixed语句。

C#错误:无法使用包含在未固定表达式中的固定大小缓冲区

因为我对Delphi不太熟悉,所以我不能直接回答tString32字段。它似乎是UnmanagedType。AnsiBStr。

如果是这样的话,我会选择这样的东西:

[StructLayout(LayoutKind.Sequential, Pack=4)]
public struct tBowler_Rec
{
    public tGender gender;
    public byte bowler_num;
    [MarshalAs(UnmanagedType.AnsiBStr)]
    public string name;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
    public char[] initials;

另请看我是如何执行initials封送处理的。如果tString不是AnsiBStr,这将是从名称封送字符的更好方法。

我还想表明,我已经从结构声明中删除了固定的和不安全的指令,因为这对于您尝试做的事情来说是不必要的。

尝试

Encoding.ASCII.GetString(name, 1, name[0]);

以原始格式存储的字符串不是"null终止的"(C风格的字符串(。

原始格式为"char-count Then count chars"=>0x6=字符数,A=0 S=1 H=2 T=3 O=4 N=5。

您尝试读取字符,直到遇到空字符。但是没有null字符,它不是以null结尾的字符串。您必须为此设置自定义数据caster或转换数据库。

我在这里找到了答案:固定大小的缓冲区不能直接从";这个";目标

解决方案:

    [StructLayout(LayoutKind.Sequential, Pack=4)]
    public unsafe struct tBowler_Rec
    {
        public tGender gender;
        public byte bowler_num;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
        public byte[] name;
        ...
        public string Name
        {
            get
            {
                StringBuilder sb = new StringBuilder();
                int ilen = name[0];
                for (int i = 1; i <= ilen; i++)
                    sb.Append(name[i]);
                return sb.ToString();
            }
        }

Vladimir绝对走在了正确的轨道上:根本问题是我需要将这个Delphi数组视为一个值类型,而不是C#(引用类型(数组。解决方案是"MarshalAs(UnmanagedType.ByValArray("/

谢谢大家!