c++-cli - C++/CLI 方法调用 native 方法来修改 int - 需要 pin_ptr?

标签 c++-cli pass-by-reference pin-ptr

我有一个 C++/CLI 方法 ManagedMethod,它有一个输出参数,该参数将由 native 方法修改,如下所示:

// file: test.cpp

#pragma unmanaged
void NativeMethod(int& n)
{
   n = 123;
}
#pragma managed

void ManagedMethod([System::Runtime::InteropServices::Out] int% n)
{
   pin_ptr<int> pinned = &n;
   NativeMethod(*pinned);
}

void main()
{
   int n = 0;
   ManagedMethod(n);
   // n is now modified
}

一旦ManagedMethod返回,n的值就按照我的预期被修改了。到目前为止,我能够编译此代码的唯一方法是在 ManagedMethod 中使用 pin_ptr,因此固定实际上是正确/唯一的方法这?或者是否有更优雅的方式将 n 传递给 NativeMethod

最佳答案

是的,这是正确的方法。在 CLR 内部进行了高度优化,该变量获得 [pinned] 属性,因此 CLR 知道它存储了一个指向不应移动的对象的内部指针。与 GCHandle::Alloc() 不同,pin_ptr<> 可以在不创建另一个句柄的情况下完成此操作。表中显示,编译方法时会产生抖动,GC 使用该表来知道在哪里寻找对象根。

只有当垃圾回收与 NativeMethod() 运行的同时发生时,这才有意义。在实践中并不经常发生,您必须在程序中使用线程。 YMMV。

还有另一种方法可以做到这一点,不需要固定,但需要更多的机器代码:

void ManagedMethod(int% n)
{
    int copy = n;
    NativeMethod(copy);
    n = copy;
}

这是有效的,因为局部变量具有堆栈存储,因此不会被垃圾收集器移动。风格上没有赢得任何优雅点,但我自己通常使用的,估计固定的副作用并不那么容易。但是,实际上,不要害怕 pin_ptr<>。

关于c++-cli - C++/CLI 方法调用 native 方法来修改 int - 需要 pin_ptr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35805303/

相关文章:

visual-studio - VS2008 : Unit Testing with Code Coverage doesn't work with/CLR

c++-cli - CLI 中的复制构造函数和赋值运算符

.net - 无法以编程方式展开分配给 TreeView 的 TreeNode

Perl:修改作为参数传递给子程序的变量

c# - 使用 CLI 数组分配的内存作为非托管类的存储

c++ - 是否需要释放 pin_ptr 还是自动完成?

.net - 是否可以通过垃圾收集创建 native 代码?

无法从 'int *' 转换为 'int'

c - 将指针传递给 C 中的函数