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

mbyulnm0  于 2023-03-01  发布在  C#
关注(0)|答案(4)|浏览(245)

我正在努力用C#程序从数据库中读取二进制记录。这些记录是用Borland Delphi创建的。下面是一个例子:

// Delphi record definition
  tBowler_Rec = Record
  public
    gender          : tGender;
    bowler_num      : byte;
    name            : tString32;
    initials        : String[3];
    ...
// Corresponding C# definition (unmanaged code)
    [StructLayout(LayoutKind.Sequential, Pack=4)]
    public unsafe struct tBowler_Rec
    {
        public tGender gender;
        public byte bowler_num;
        public fixed byte name[32];
        public fixed byte initials[3];
        ...

我实际上能够从SQL Server数据库中读取这个二进制结构,并在Visual Studio调试器中查看数据。耶!我能够访问像"gender"和"bowler_num"这样的字段,没有任何问题。耶!
问:如何将"name"转换为C#字符串?
一个示例名称是"ASHTON"。它在内存中如下所示:

\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语句。

bwntbbo3

bwntbbo31#

由于我对 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,这将是封送name中的字符的更好方法。
我还想说明一下,我已经从结构声明中删除了固定的和不安全的指令,因为这对您要做的事情来说是不必要的。

wd2eg0qa

wd2eg0qa2#

试试看

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

piztneat3#

以原始格式存储的字符串不是“null terminated”(C样式字符串)。
原始格式是'字符计数然后计数字符=〉0x6 =字符计数,A = 0 S = 1 H = 2 T = 3 O = 4 N = 5。
您尝试读取字符,直到遇到空字符。但是没有空字符,它不是空终止字符串。您必须为此设置自定义数据转换器或转换数据库。

mpgws1up

mpgws1up4#

我在这里找到了答案:Fixed size buffer cannot be directly used from "this" object
溶液:``

[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();
            }
        }

弗拉基米尔绝对是在正确的轨道上:根本问题是我需要将这个Delphi数组作为值类型,而不是C#(引用类型)数组来处理。解决方法是"MarshalAs(UnmanagedType.ByValArray)"/
谢谢大家!

相关问题