C# 如何获取位数组中位的字节*? 我正在研究一个C++ API的C++CLI包装器。C API中的一个函数需要以下格式的数据: void setData(byte* dataPtr, int offset, int length); void getData(byte* buffer, int offset, int length); 对于C++ CLI,建议使用Sytal.Copyth.BITSART(是的,每个位都有意义)。可以从字节数组构造位数组,并将其复制到: array<System::Byte>^ bytes = gcnew array<System::Byte>(40); System::Collections::BitArray^ ba = gcnew System::Collections::BitArray(bytes); int length = ((ba->Length - 1)/8) +1; array<System::Byte>^ newBytes = gcnew array<System::Byte>(length); ba->CopyTo(newBytes, 0); pin_ptr<unsigned char> rawDataPtr = &buffer[0]; array^bytes=gcnewarray(40); System::Collections::BitArray ^ba=gcnew System::Collections::BitArray(字节); int-length=((ba->length-1)/8)+1; 数组^newBytes=gcnew数组(长度); ba->CopyTo(新字节,0); pin_ptr rawDataPtr=&缓冲区[0];

C# 如何获取位数组中位的字节*? 我正在研究一个C++ API的C++CLI包装器。C API中的一个函数需要以下格式的数据: void setData(byte* dataPtr, int offset, int length); void getData(byte* buffer, int offset, int length); 对于C++ CLI,建议使用Sytal.Copyth.BITSART(是的,每个位都有意义)。可以从字节数组构造位数组,并将其复制到: array<System::Byte>^ bytes = gcnew array<System::Byte>(40); System::Collections::BitArray^ ba = gcnew System::Collections::BitArray(bytes); int length = ((ba->Length - 1)/8) +1; array<System::Byte>^ newBytes = gcnew array<System::Byte>(length); ba->CopyTo(newBytes, 0); pin_ptr<unsigned char> rawDataPtr = &buffer[0]; array^bytes=gcnewarray(40); System::Collections::BitArray ^ba=gcnew System::Collections::BitArray(字节); int-length=((ba->length-1)/8)+1; 数组^newBytes=gcnew数组(长度); ba->CopyTo(新字节,0); pin_ptr rawDataPtr=&缓冲区[0];,c#,c++-cli,bit,C#,C++ Cli,Bit,我关心的是最后一行。以这种方式从数组中获取指针有效吗?在C#中是否有更好的替代方法来处理任意位?记住,每个位都有意义 以这种方式从数组中获取指针有效吗 是的,这是有效的。pin_ptr helper类在引擎盖下调用GCHandle.Alloc(),请求GCHandleType.pinted。因此指针是稳定的,可以传递给非托管代码,而不用担心垃圾收集器会移动数组并使指针无效 然而,问题中缺少一个非常重要的细节。pin_ptr之所以存在而不只是让您直接使用GCHandle,是因为在调用GCHandl

我关心的是最后一行。以这种方式从数组中获取指针有效吗?在C#中是否有更好的替代方法来处理任意位?记住,每个位都有意义

以这种方式从数组中获取指针有效吗

是的,这是有效的。pin_ptr helper类在引擎盖下调用GCHandle.Alloc(),请求GCHandleType.pinted。因此指针是稳定的,可以传递给非托管代码,而不用担心垃圾收集器会移动数组并使指针无效

然而,问题中缺少一个非常重要的细节。pin_ptr之所以存在而不只是让您直接使用GCHandle,是因为在调用GCHandle.Free()方法时,恰好是。你不明确地这样做,PiN-PTR为你做,它使用标准的C++ RAII模式。换句话说,当变量超出范围时,会自动调用Free()方法。它得到C++编译器发出析构函数调用,它依次调用For()。 当C函数存储传递的数据ptr并在以后使用它时,这将非常非常错误。后来的问题是,阵列将不再被固定,现在可以存在于任意地址。主要数据损坏,很难诊断。getData()函数强烈表明事实就是如此。这不好

您需要解决这个问题,您自己使用GCHandle::Alloc()永久固定数组对垃圾收集器来说是非常痛苦的,垃圾收集器是一块不易移动的石头,对程序的效率有着长期的影响。相反,您应该将托管阵列复制到使用malloc()或Marshal::allocglobal()分配的稳定内存中。这是非托管内存,它永远不会移动。Marshal::Copy()是复制它的一种简单方法

以这种方式从数组中获取指针有效吗

是的,这是有效的。pin_ptr helper类在引擎盖下调用GCHandle.Alloc(),请求GCHandleType.pinted。因此指针是稳定的,可以传递给非托管代码,而不用担心垃圾收集器会移动数组并使指针无效

然而,问题中缺少一个非常重要的细节。pin_ptr之所以存在而不只是让您直接使用GCHandle,是因为在调用GCHandle.Free()方法时,恰好是。你不明确地这样做,PiN-PTR为你做,它使用标准的C++ RAII模式。换句话说,当变量超出范围时,会自动调用Free()方法。它得到C++编译器发出析构函数调用,它依次调用For()。 当C函数存储传递的数据ptr并在以后使用它时,这将非常非常错误。后来的问题是,阵列将不再被固定,现在可以存在于任意地址。主要数据损坏,很难诊断。getData()函数强烈表明事实就是如此。这不好


您需要解决这个问题,您自己使用GCHandle::Alloc()永久固定数组对垃圾收集器来说是非常痛苦的,垃圾收集器是一块不易移动的石头,对程序的效率有着长期的影响。相反,您应该将托管阵列复制到使用malloc()或Marshal::allocglobal()分配的稳定内存中。这是非托管内存,它永远不会移动。Marshal::Copy()是复制它的一种简单方法。

坦率地说,我会远离BitArray—只使用byte[]或byte*,以及移位运算符和掩码,等等。简而言之,我会远离BitArray—只使用byte[]或byte*,以及移位运算符和掩码,不幸的是,
BitArray::CopyTo
无法直接写入非托管内存,并且完全跳过了临时托管数组。由于我无法对您的答案进行投票,我将简单地评论这是一个很好的答案,并解释了固定GC堆内存的必要性。然而,它并没有回答我想问的问题。&buffer[0]是否指向包含数组内容的连续内存块的开头?我想,既然你没有对此发表评论,那么它肯定会发表评论,但我不想这样假设。:-)对总之是很短的一段时间。不幸的是,
BitArray::CopyTo
无法直接写入非托管内存,并且完全跳过了临时托管数组。由于我无法对您的答案进行投票,我将简单地说明这是一个很好的答案,并解释了固定GC堆内存的必要性。然而,它并没有回答我想问的问题。&buffer[0]是否指向包含数组内容的连续内存块的开头?我想,既然你没有对此发表评论,那么它肯定会发表评论,但我不想这样假设。:-)对反正是很短的一段时间。