Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否需要固定相邻固定大小的缓冲器? 我一直在把一个旧的C++应用程序移植到C语言上,我不确定我的解决方案是否可行。_C#_Pinning - Fatal编程技术网

C# 是否需要固定相邻固定大小的缓冲器? 我一直在把一个旧的C++应用程序移植到C语言上,我不确定我的解决方案是否可行。

C# 是否需要固定相邻固定大小的缓冲器? 我一直在把一个旧的C++应用程序移植到C语言上,我不确定我的解决方案是否可行。,c#,pinning,C#,Pinning,最让人头疼的是,应用程序的文件格式本质上只是一些(相当大的)转储到文件中的结构。有趣的是,这种格式要求整数以大端顺序排列,而与系统无关。因此,我把一个实用方法扔进字节顺序,并构造了使用大量固定大小的缓冲区复制C++布局的结构。此时,导入就像将文件复制到内存并使用一样简单,这比手动读取要容易得多,但不允许在构建时翻转字节顺序 因此,格式在很大程度上依赖于短变量,包括单个变量和固定缓冲区中的变量。当我把许许多多的固定语句放在一起以固定翻转的缓冲区时,我有一个令人不安的想法 除非我弄错了,否则只固定其

最让人头疼的是,应用程序的文件格式本质上只是一些(相当大的)转储到文件中的结构。有趣的是,这种格式要求整数以大端顺序排列,而与系统无关。因此,我把一个实用方法扔进字节顺序,并构造了使用大量固定大小的缓冲区复制C++布局的结构。此时,导入就像将文件复制到内存并使用一样简单,这比手动读取要容易得多,但不允许在构建时翻转字节顺序

因此,格式在很大程度上依赖于短变量,包括单个变量和固定缓冲区中的变量。当我把许许多多的固定语句放在一起以固定翻转的缓冲区时,我有一个令人不安的想法

除非我弄错了,否则只固定其中一个缓冲区会导致整个结构被固定(将结构的一部分从其余部分重新定位是没有意义的)。所以,我试过这样的方法:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct Example
{
    short value1;
    fixed short value2[10];
    short value3;
    fixed short value4[20];

    public void FlipEndianness()
    {
        fixed (short* ptr = &value1)
        {
            Utility.FlipShorts(ptr, 32);
        }
    }
}
其思想是,实用程序方法处理指针和计数,像数组一样迭代指针-我最初编写它是为了翻转缓冲区,但我在这里看到了值。从理论上讲,它似乎工作正常——所有的变量都在一次调用中翻转,没有那么麻烦。我需要知道的是我的概念是否真的安全。手动固定所有东西都会是一个巨大的痛苦-我提到过结构是巨大的吗


固定一个变量是否会固定整个结构并使这种欺骗成为可能,或者我只是幸运到目前为止,这还没有占用内存?到目前为止,我的测试结果是肯定的,但我不能肯定。我不想让这个爆炸发生在我身上。

据我所知,没有任何资源可以告诉你在C#中这样做是安全的。但是你会侥幸逃脱的,GC中没有一种机制可以固定一个struct字段,同时允许struct中的其他字段移动。这样的固定语句会创建一个固定的内部指针,GC足够聪明,可以从中发现对象根。在C++/CLI的文献中只提到过内部指针,这种语言允许使用
Interior\u ptr
关键字直接声明内部指针。请注意,这在另一个CLR实现(如Mono)上不一定能很好地工作。YMMV。C++/CLI是更好的武器,至少你可以使用原来的C或C++声明,而不必在C++中重写。您将有一个指向本机结构的稳定指针

首先,这不应该是一个问题,只有当结构是在GC堆上分配的引用类型的一部分时,才需要实际的对象固定。不知道您的代码是什么样子的,但是一种明智的方法是在读取和转换数据的方法中保持这样一个结构作为局部变量。此类值类型在堆栈上分配,并具有稳定的地址


请注意,这段代码中有大量不安全的代码,编译器和运行时都不能对您错误地使用magic 32值做任何处理。优化文件数据转换代码很少有用,读取数据的成本比解释数据高出几个数量级。如此之多以至于使用反射来找到字段是合理的,这样你就永远不会弄错。Jon Skeet的EndianBinaryReader也应该提到。

欢迎来到Stack Overflow!请不要在问题标题中包含有关语言的信息,除非没有它就没有意义。标签可以实现这个目的。如果在非托管缓冲区中允许更改数据,则可以在编组前使用<代码> ItPtR.TopoTeIn()/Cuth.I。我确实考虑了C++ + CLI,但再一次,虽然我非常清楚C,并且在C++中是可以通过的,但这是完全不同的动物。我希望避免仅仅为了整个项目的一个特定部分而学习一门新语言。至于EndianBinaryReader,我特别尝试通过将其作为块读入来避免这种情况。在我的结构中有很多很多字段和数组,所以使用任何二进制读取器都会非常繁琐和耗时。我开始这么做,很快改变了主意。