将代码 c++ 转换为 c#,读取到类
Convert code c++ to c# , read to a class
我有一个类
class DataqFmt
{
public:
unsigned short SR_number;
unsigned short SR_numerator;
unsigned char offset;
unsigned char nbytes;
short hdr_bytes;
unsigned long dat_bytes;
char dummy[1144];
};
代码 C++ :
afl = fopen(path, "rb");
DataqFmt dataqstr;
fread ((char*) &dataqstr, sizeof (dataqstr), 1, afl);
如何将此代码 c++ 转换为 c# .请帮助我
我将假设编写此文件的C++应用程序是为 Win32 x86 编译并在 Win32 x86 上运行的。这使我能够对DataqFmt
安排的方式做出假设。如果这些假设是错误的,您可以使用StructLayout
和相关属性的各种选项(如 MarshalAs
和 FieldOffset
)来调整它们。
首先,我们将使用与 DataqFmt
布局相同的 C# 结构:
[StructLayout(LayoutKind.Sequential)]
struct DataqFmtCs
{
public ushort SR_number; // assuming the C++ type unsigned short is 2 bytes
public ushort SR_numerator;
public byte offset; // assuming the C++ type unsigned char was an unsigned and 1 byte
public byte nbytes;
public short hdr_bytes; // assuming the C++ type short was 2 bytes
public uint dat_bytes; // assuming the C++ type unsigned long was 4 bytes
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1144)]
public sbyte[] dummy; // assuming the C++ type char was signed and 1 byte
}
有了这种结构,我们现在需要执行文件 I/O 来获取原始字节。
int dataqfmtSize = Marshal.SizeOf(typeof(DataqFmtCs));
var buffer = new byte[dataqfmtSize];
using (var fs = File.OpenRead("path\to\the\file")) {
int bytesRead = fs.Read(buffer, 0, buffer.Length);
if (bytesRead != buffer.Length) {
// handle this
}
DataqFmtCs someThing = GetDataqFmtFromBuffer(buffer);
}
最后,我们有转换例程GetDataqFmtFromBuffer
。
private static DataqFmtCs GetDataqFmtFromBuffer(byte[] buffer) {
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try {
return (DataFmtCs)Marshal.PtrToStructure(
handle.AddrOfPinnedObject(),
typeof(DataFmtCs));
} finally {
handle.Free();
}
}
Marshal.PtrToStrucutre
正在做绝大多数的转换工作。代码的其余部分只是定义结构并执行基本的 .NET 文件 I/O。
另一种选择(如果您使用的是与平台无关的文档齐全的协议,这通常是一个很好的解决方案,因为您通常需要执行字节序转换)是编写一个反序列化例程,该例程使用 BinaryReader
在Stream
上运行。我把这个留给你做一个练习。
如果您使用的是Visual Studio,则还可以导入C++代码并将其编译为CLR库,以供任何其他.net程序集引用。 如果您需要C++代码快速运行,这尤其是一个好主意。
如果你愿意承认 fread() C++本质上是脆弱且不可移植的,那么最好编写一个抽象层来读取(和写入)代码数据类型,例如,这样的格式很有用:
// returns true on success, false on EOF
public static bool Read(Stream stm, out int val)
{ /* ... */ }
public static bool Read(Stream stm, out short val)
{ /* ... */ }
然后,您可以将代码编写为如下所示:
if (!Read(stm, out _someMember))
throw SomeException(); // or return a fail code
if (!Read(stm, out _someOtherMember))
throw SomeException();
或者在我的一些代码的情况下,我编写了一个方法,该方法给定一个对象、一个流和一个字段或属性的名称,读取适当的大小值并设置成员(如果找不到它,则引发异常),然后是一个类似的方法,它适用于一个对象和一个名称集合(或者实际上是可变数量的字符串参数, 所以初始化可以看起来像这样:
public static TTHorizontalHeader FromStream(Stream stm)
{
TTHorizontalHeader header = new TTHorizontalHeader();
if (!Reader.ReadType(stm, header,
"TableVersion", "Ascender", "Descender", "LineGap", "AdvanceWidthMax", "MinLeftSideBearing",
"MinRightSideBearing", "XMaxExtent", "CaretSlopeRise", "CaretSlopeRun", "CaretOffset", "Reserved0",
"Reserved1", "Reserved2", "Reserved3", "MetricDataFormat", "NumberOfHMetrics"))
return null;
return header;
}
但是你说,"C++不会跑得更快,因为它只做一个fread()?我回答说:"Endianess、数据类型大小、结构填充和对象布局的变化足以让我们不以性能为幌子继续传播相同的脆弱代码。 无论如何,任何像样的缓冲流都只会进行一次实际读取,并且读取工作是由公正的机器人完成的。 除了 I/O 的成本,无论是否缓冲,都将使反射和字符串迭代的成本相形见绌。
- 读取最后一行代码算法 - c++ 时出现问题
- 我编写了以下代码来读取C++矩阵,然后打印其行和列.我收到此错误
- 如何使用指针直接从托管代码中的非托管代码中读取矢量数据
- 在 c++ 中逐行读取文件(将代码从 Python 转换为 C++)
- 使用 Visual Studio 代码读取 C++ 中的输入流时出错
- 如何只读取和剥离特定的代码行
- boost::asio-async_read_some示例代码没有读取套接字中的所有数据
- 从C++代码中直接读取成员属性
- 驱动程序,以支持从 C++ 代码读取或写入 HIVE
- 读取代码中的文件版本值
- 如何让这个C++代码从用户那里读取五个整数而不是一个整数?
- C++ - 使用代码块从文件中读取 IP 地址
- 为什么 ifstream 文件中的换行符 - 当被此代码读取时 - 占用 2 个字节
- 我在编写从文本文件中读取数据并按升序打印的代码时遇到问题
- 为什么此代码无法正确读取用户输入
- 结构无法正确读取C++代码::块 13.12
- 无法读取代码页不匹配的文件版本信息
- 读取代码行的数量
- 使用引用和取消引用运算符读取代码行时遇到问题
- 从.txt [c++]读取代码