这不是如果文件中的记录包含一个字符串,那么你声明的结构相似,你会如何声明它在C:
struct Example {
int mumble; // Anything, not necessarily a string length
char text[42];
// etc...
};
等价的C#声明会是什么样子:
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
private struct Example {
public int mumble;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 42)]
public string text;
// etc...
}
您通常会使用BinaryReader来读取数据。但它不能直接处理这样的字符串,你必须将它们作为byte []读取,然后自己进行字符串转换。你也不能利用声明语法,你必须为结构的每个成员编写一个调用。
有一个解决方法,Marshal类已经知道如何使用PtrToStructure()方法将非托管结构转换为托管结构。这是一个通用的实现,它适用于任何blittable类型。两个版本,一个是从byte []读取的静态文件,另一个是从流中重复读取的实例方法。你会使用一个FileStream或MemoryStream。
using System;
using System.IO;
using System.Runtime.InteropServices;
class StructTranslator {
public static bool Read<T>(byte[] buffer, int index, ref T retval) {
if (index == buffer.Length) return false;
int size = Marshal.SizeOf(typeof(T));
if (index + size > buffer.Length) throw new IndexOutOfRangeException();
var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try {
IntPtr addr = (IntPtr)((long)handle.AddrOfPinnedObject() + index);
retval = (T)Marshal.PtrToStructure(addr, typeof(T));
}
finally {
handle.Free();
}
return true;
}
public bool Read<T>(Stream stream, ref T retval) {
int size = Marshal.SizeOf(typeof(T));
if (buffer == null || size > buffer.Length) buffer = new byte[size];
int len = stream.Read(buffer, 0, size);
if (len == 0) return false;
if (len != size) throw new EndOfStreamException();
var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try {
retval = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
}
finally {
handle.Free();
}
return true;
}
private byte[] buffer;
}
未经测试,希望它能正常工作。
您提出的C代码有问题,因此您将其转换为C#的机会注定要失败! – 2010-10-05 11:32:47
这取决于。多少条数据记录?他们多大? – 2010-10-05 11:34:44