interior_ptrとpin_ptr

CLAPACKの関数は,全ての引数をポインタで渡さなければなりません(in/outに関係なく).しかし,VectorやMatrixはref classであるため,

ref class Hoge
{
private:
    int    size;
public:
    void foo()
    {
        native_func(&size);    // error !
    }
};

Hoge^ h = gcnew Hoge();
int* p = &(h->size);    // error !

のようなことができません.ポインタを直接とりたい場合は,pin_ptrを使います.

Hoge^ h = gcnew Hoge();
pin_ptr<int> pp = &(h->size);
int* p = pp;

しかし,渡すポインタがさしている変数に対して,変更を反映させる必要が無ければ,一度ローカル変数にしてから渡した方が良いと思います.

ref class Vector
{
public:
    Vector^ operator*=( const double n )
    {
        integer    S = m_size;
        doublereal N = n;
        integer    incX = 1;
        dscal_(&S, &N, m_array, &incX);
        return this;
    }
};

※integer, doublereal, dscal_ は,CLAPACKで使われている型名や関数名

interior_ptrとpin_ptrの違いは,

  • interior_ptrは,ポイントしているオブジェクトがガベージコレクタによって移動してしまっても,きちんと追跡を行います.
  • pin_ptrは,ポイントしているオブジェクトが移動してしまわないよう,固定してしまいます.しかし,スコープを越えて使用することができません(関数の戻り値とかにできないということ).


参考