__pin

本主题仅适用于托管扩展的 1 版 C++ 的请注意。 只应在此语法维护 1 版代码。 有关使用等效功能的信息在新语法,请参见 pin_ptr

防止对象或托管类的嵌入对象将由公共语言运行时 (clr) 垃圾回收时。

__pin identifier

备注

__pin 关键字声明指向对象或托管类的嵌入对象并防止对象将在垃圾回收期间在公共语言运行时。 这是有用,将通过托管类的地址传递给非托管函数时,因为该地址不会在非托管解析时意外更改函数调用。

钉住指针在其词法范围保持有效。 当钉住指针超出范围,对象不再被视为锁定,当然, (除非存在指向或到对象) 的其他钉住指针。

MSIL 没有概念 “块范围”--在函数范围内,所有局部变量中。 若要告知系统锁不再起作用,编译器会生成分配空锁定的指针的代码。 这也是可执行 hello,因此,如果需要断开对象,而不保留块。

不应将钉住指针转换为非托管指针并继续使用此非托管指针,在对象不再锁之后 (在钉住指针超出范围)。 不同 gc 指针,钉住指针可以转换为 nogc,非托管指针。 但是,在中,当非托管指针正在使用时,用户将负责维护锁。

使用钉住指针获取一个变量的地址然后使用该地址,在钉住指针超出范围后,不应完成。

// keyword_pin_scope_bad.cpp
// compile with: /clr:oldSyntax /LD
#using <mscorlib.dll>
__gc struct X {
   int x;
};
 
int* Get_x( X* pX ) {
   int __pin* px = &pX -> x;
   return px;   // BE CAREFUL px goes of scope, 
                // so object pointed by it is no longer pinned,
                // making the return value unsafe.
}

下面的示例显示正确的行为:

// keyword_pin_scope_good.cpp
// compile with: /clr:oldSyntax /LD
#using <mscorlib.dll>
__gc struct X {
   int x;
};
 
int Get_x( X* pX ) {
   int __pin* px = &pX -> x;
   return *px;   // OK, value obtained from px before px out of scope
}

示例

在下面的示例中, pG 所指向的对象锁定,直到超出范围:

// keyword__pin.cpp
// compile with: /clr:oldSyntax
#using <mscorlib.dll>
#include <iostream>

__gc class G { 
public: 
   int i; 
   G() {i = 0;};
};

class H {
public:
   // unmanaged function
   void incr(int * i) {
      (*i)++; 
      std::cout << *i << std::endl;
   };
};

int main() {
   G __pin * pG = new G;  // pG is a pinning pointer
   H * h = new H;
   // pointer to managed data passed as actual parameter of unmanaged 
   // function call
   h->incr(& pG -> i); 
}

Output

1