C++ cli 是否可以在不使用pin_ptr的情况下将托管字节数组强制转换为本机结构,从而避免对GC造成太多错误?

C++ cli 是否可以在不使用pin_ptr的情况下将托管字节数组强制转换为本机结构,从而避免对GC造成太多错误?,c++-cli,C++ Cli,可以仅使用pin_ptr,AFAIK将托管数组^强制转换为一些非托管结构,如: void Example(array<Byte>^ bfr) { pin_ptr<Byte> ptr = &bfr[0]; auto data = reinterpret_cast<NonManagedStruct*>(ptr); data->Header = 7; data->Length = sizeof(data);

可以仅使用
pin_ptr
,AFAIK将托管
数组^
强制转换为一些非托管
结构
,如:

void Example(array<Byte>^ bfr) {
    pin_ptr<Byte> ptr = &bfr[0];
    auto data = reinterpret_cast<NonManagedStruct*>(ptr);
    data->Header = 7;
    data->Length = sizeof(data);
    data->CRC = CalculateCRC(data);
}
void示例(数组^bfr){
pin_ptr ptr=&bfr[0];
自动数据=重新解释铸件(ptr);
数据->标题=7;
数据->长度=尺寸(数据);
数据->CRC=计算ECRC(数据);
}
但是,是否以任何方式使用了
内饰\u ptr

我宁愿以低级方式处理托管数据(使用
union
s、
struct
-位字段,等等),而不固定数据-我可能会持有此数据很长时间,不想干扰
GC

澄清:
我不想将托管数据复制到本机和本机(因此这里不能选择
封送处理方式…

您可能不会用
pin_ptr
骚扰GC-它与
GCHandle
不同,非常轻量级

GCHandle::Alloc(someObject,GCHandleType::pinted)
实际上会将对象注册为被固定在GC中。这允许您在较长的时间内和跨函数调用锁定对象,但GC必须跟踪该对象

另一方面,
pin_ptr
被转换为固定的本地in-IL代码。GC不会得到通知,但它会看到对象仅在收集期间被固定。也就是说,在堆栈上查找对象引用时,它会注意到它的固定状态


如果确实需要,可以通过以下方式访问堆栈内存:

[StructLayout(LayoutKind::Explicit, Size = 256)]
public value struct ManagedStruct
{
};

struct NativeStruct
{
    char data[256];
};

static void DoSomething()
{
    ManagedStruct managed;
    auto nativePtr = reinterpret_cast<NativeStruct*>(&managed);
    nativePtr->data[42] = 42;
}

…编译器也会在幕后为您表演类似的把戏。

从您的回答中,我认为使用
interior\u ptr
进行本机铸造是不可能的,对吗?那么,如何将某些字节数组视为本机结构?如果不固定它,我就不能这样做?事实上,你不能这样做是有充分的理由的:如果托管对象没有固定,它可以被GC重新定位,而你不希望在本机代码中使用它时发生这种情况。请参阅我的编辑,了解一个没有钉住的实际示例,但恐怕这与实际情况无关。唉,无休止的封送是必须的。。。这就是为什么我期待GC与C++共存的日子,或是用GC捕获控制的本地语言(如<代码> d>代码>)。或者至少
C #
开始很好地处理位…不需要封送。。。如果您使用pin:-)实际上,没有必要担心pinning,除非您可以通过分析来证明它具有严重的影响(我敢打赌,您的托管/本机转换thunk对性能的影响将比pinning大得多)。
static void DoSomething()
{
    NativeStruct native;
    native.data[42] = 42;
}