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语句。
因为我对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("/
谢谢大家!