简体   繁体   English

用指针在C#中编写一个二进制文件以供C程序读取?

[英]Writing a binary file in C# to be read by C program, with pointers?

I'm moving some old C code that generates a binary file into our C# system. 我正在移动一些旧的C代码,这些代码会在我们的C#系统中生成一个二进制文件。 The problem is, the resulting binary file will still need to be read by another old C program. 问题是,生成的二进制文件仍将需要由另一个旧的C程序读取。

The original code outputs several structs to a binary file, and many of those structs contain linked lists, with *next pointers. 原始代码将多个结构输出到二进制文件,其中许多结构包含带有* next指针的链表。

How can I write these in C# so that the original program will still be able to read them? 我该如何用C#编写这些代码,以便原始程序仍然能够读取它们?

The old C code reads and writes the file a whole struct at a time, with freads and fwrites ie 旧的C代码一次读取和写入整个结构的文件,具有freads和fwrites即

fread ( &file, sizeof ( struct file_items ), 1, hdata.fp );

I can't find a whole lot of info on how fwrite would output the pointers, etc. 我找不到关于fwrite如何输出指针等的大量信息。

If the old code was writing pointers to a file, then odds are you dealing with very poorly written code. 如果旧代码正在编写指向文件的指针,那么您处理非常差的代码的可能性就很大。 Those pointers would be meaningless to any other process reading that file... 这些指针对读取该文件的任何其他进程毫无意义。

Also, reading whole structures with a single fread() is a bad idea because different compilers may pad those structures differently (so the structure written by one application may be laid out differently than one read by another application). 同样,用单个fread()读取整个结构也是一个坏主意,因为不同的编译器可能会对这些结构进行不同的填充(因此,一个应用程序编写的结构的布局可能不同于另一应用程序所读取的结构)。

If your code is depending on reading and writing pointer values to a file then it's broken. 如果您的代码取决于读写指针值到文件,那么它就坏了。 Every time you run the program it could potentially have a slightly different memory layout. 每次您运行该程序时,其内存布局都可能会略有不同。

Instead of writing pointers you should probably convert the pointers into file offsets on write and convert the file offsets back to pointers on read. 除了写指针,您可能应该在写时将指针转换为文件偏移,并在读时将文件偏移转换回指针。

(This is true for C, C++ and C#) (对于C,C ++和C#是正确的)

The pointers will be meaningless after reading them back, in C or any other language. 用C或任何其他语言读回指针后,它们将毫无意义。 I assume the pointer-structures are rebuild after reading. 我假设指针结构在读取后会重建。 This means you can just treat them as fillers while reading/writing. 这意味着您可以在读/写时将它们视为填充符。

In .NET, streams only accept byte and byte[] as data types, so you will have to convert your structs to/from that format. 在.NET中,流仅接受bytebyte[]作为数据类型,因此您必须将结构转换为该格式。

One way is to write custom code reading/writing the fields in order. 一种方法是编写自定义代码,以按顺序读取/写入字段。 Gives you the most control but it is a lot of work. 给您最大的控制权,但这是很多工作。

The other approach is to map your struct to a byte[] wholesale, I'll look for an example. 另一种方法是将您的结构映射到byte []批发,我将找一个例子。

The only way you can be (correctly) writing pointers to disk is if you are using something like based addressing : 您可以(正确)将指针写到磁盘的唯一方法是,如果您正在使用类似基于基址的地址

A linked list that consists of pointers based on a pointer can be saved to disk, then reloaded to another place in memory, with the pointers remaining valid. 可以将由基于指针的指针组成的链表保存到磁盘,然后重新加载到内存中的其他位置,并使指针保持有效。

Handling this in C# would be extremely difficult and require some kind of mapping layer during serialization. 用C#处理此问题将非常困难,并且在序列化过程中需要某种映射层。

A pointer refers to a memory location, when you store a pointer in a file, it is meaningless, it refers to something that is ephemeral. 指针指的是内存位置,当您将指针存储在文件中时,它是没有意义的,它指的是短暂的东西。 So either it does not matter in this application because the data referenced is discared, or you have not stated the format correctly. 因此,在该应用程序中这无关紧要,因为所引用的数据已被舍弃,或者您没有正确说明格式。 Normally in such a case you would apply 'serialization', so that the data pointed to were also stored, in the file in such a way that the original data and what it pointed to could be reconstructed ('deserialized') at a later time. 通常,在这种情况下,您将应用“序列化”,以便将指向的数据也存储在文件中,以便可以在以后的时间重建(“反序列化”)原始数据及其指向的内容。 。

There is no fundamental difference between file storage in C and C# - that is independent of the language, however there may be differences in structure packing, so just storing the structure was always a bad idea (structure packing can vary even between C compilers). C和C#中的文件存储之间没有根本的区别-独立于语言,但是结构打包可能存在差异,因此仅存储结构始终是一个坏主意(即使在C编译器之间,结构打包也会有所不同)。 Also of course you need to realise that a char type in C# is 16-bit, not 8. You need to let the existing storage format be the specification and then implement it in C# using serialisation to avoid problems with the differences in structure implementation. 当然,当然您还需要认识到C#中的char类型是16位而不是8位。您需要让现有的存储格式成为规范,然后使用序列化在C#中实现它,以避免结构实现上的差异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM