.net経由で生ポインタを渡す
そもそもそんな必要があるのかと思われるかもしれないが事実ありえたんですよ!
あるアプリ(C#)から二つのクラスライブラリ(両方ともC++/CLI)を参照しており、ライブラリ同士の依存関係はなし。なのでライブラリ同士でデータを受け渡す場合は.netの型にして本体を経由する。しかしライブラリの中身はnativeなので実際扱っているデータも両方ともnativeなのだ。なので.netの型にしないで直接nativeで受け渡し(要するにポインタ)が出来た方がうれしい訳だ。まあ確かにC#ならポインタも一応扱えるがunsafeなので出来れば隠蔽したい。ならばそういうクラスライブラリを作るという手もあるが保守の都合上2つのライブラリの独立性を保ちたい。じゃあどうすればいいか? 自作せずに標準ライブラリを駆使してポインタの受け渡しするには・・・と探していたらどうやらIntPtrを使えばいいっぽいことに気がついた。
//クラスライブラリ1:メモリを渡す側 public ref class Lib1{ public: IntPtr GetPtr(){ unsigned char* ptr = new unsigned char[size]; return IntPtr( ptr ); //↑IntPtrのコンストラクタにポインタを入れる。 } } };
//クラスライブラリ2:メモリを受け取る側 public ref class Lib2{ public: void SetPtr( IntPtr ptr ){ unsigned char* p = reinterpret_cast< unsigned char* >( ptr.ToPointer() ); //↑ToPointerで生のポインタを取り出す。 } } };
//app側のC# Lib1 lib1 = new Lib1; Lib2 lib2 = new Lib2; IntPtr ptr = lib1.GetPtr(); lib2.SetPtr( ptr ); //↑IntPtrは.netの型なのでunsafe不要
これでピンの回数も劇的に減らせそうだ