我需要将数据库中的blob字段读入c#app。
然而,使用以下方法,Delphi App将blob字段写入数据库:
procedure WriteABlob(Blob : TBlobField; var Buffer; size : integer);
var
s : String;
begin
setlength(s,size);
move(buffer,s[1],Size);
Blob.Value := S;
end;
写入数据库的结构不是一个简单的结构,包含
之类的内容MyVariable : Array[0..3] of String[80];
或者更糟糕的是其中一些包含
MyRecord = Packed Record
case byte of
1: (
iValue:Integer;
)
2: (
cValue:Char;
)
end;
我一直在尝试从数据库中读取字节,然后使用
Marshal.PtrToStructure()
将其移入struct
我的结构定义如下:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1, Size = 10710)]
public struct MyBlobField
{
...
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.AnsiBStr,SizeConst = SpecificArraySize)]
public String[] ArrayofFixedLengthStrings;
...
}
但是在调用Marshal.PtrToStructure()时出现错误:
无法组织战场 'ArrayofFixedLengthStrings'的类型 'MyBlobField':无效 托管/非托管类型组合 (String []必须与a配对 LPStr,LPWStr,BStr或的ArraySubType LPTSTR)。
我想知道是否有一个我可以在CustomMarshaler上定义的属性,它可以接受与String []
的配对任何想法如何将blob的内容读入c#?
答案 0 :(得分:2)
想出来......
将结构String20声明为
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct String20
{
[MarshalAs(UnmanagedType.U1)]
public byte StringSize;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public String Value;
}
显然,固定长度字符串(即delphi ShortString)开头的字符串大小标识符只有1个字节。 然后将header_identifiers的定义更改为:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = max_header_identifiers)]
public String20[] header_identifiers;
还发现Delphi Packed Boolean需要转换为
[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
答案 1 :(得分:0)
我的第一个评论是“String [80]”是一个固定长度的字符串(在结构中应该更容易处理),在C#中你试图将它放入“String []” - 这实际上是字符串的引用(指针)。
我的下一个评论是,在最坏的情况下,你可以尝试将其读入一个字节数组,然后拉出你需要的字节并将它们操作到目标结构中。