- C#, C♯, C#相談室 Part86 [転載禁止]©2ch.net
940 :デフォルトの名無しさん[sage]:2015/03/25(水) 11:05:15.10 ID:02yD7H6L - >>938
pin_ptrとかはC++/CLIだよね?それらをC#でやる場合で良いのかな? 通常はネイティブコードと連携するならプラットフォーム呼び出し(P/Invoke)を使う (DllImport属性の適用されたstatic externで外部実装されるメソッド宣言) その際の参照云々について、Blittable型はそのまんまref/outでもいける それ以外はIn,Out属性を設定し、MarshalAs属性でメモリレイアウトを制御する unsafeならBlittable型は普通にポインター宣言できるし、それに対するC++同様の演算も出来る safeコードならvoid*に相当するIntPtrとして受け取り、メモリレイアウトが同一ならSafeBuffer、 メモリレイアウトが異なりマーシャリングが必要ならMarshalクラスの各メソッドを使うことも出来る ちなみにfixedや&に相当するGCHandle.AddrOfPinnedObject、Marshal.UnsafeAddrOfPinnedArrayElementもあるでよ
| - C#, C♯, C#相談室 Part86 [転載禁止]©2ch.net
945 :デフォルトの名無しさん[sage]:2015/03/25(水) 19:25:17.06 ID:02yD7H6L - >>943-944
IntPtr自体はポインタじゃないのでデリファレンスは無理(C++で言えばINT_PTR、ポインター長のint ポインタで受け取るならアンセーフコードの許可してunsafeメソッドにしC#でもint* pとしてp[i]で参照する アンマネージからはポインタを直接返せば良いけど…ネイティブ側でバッファを用意するのはあまり良くないかな C#でnew int[]したものを[Out]属性で渡して(アンマネージ側の受け取りはint*)、サイズも渡して書き込んでもらう方が C#側でポインタを使わなくて済むし、GCが解放する、C#側で配列を用意するのが都合悪ければ仕方が無いが… たとえばReadProcessMemoryなんかはこれでマネージ配列に突っ込んでくれるよ [DllImport("kernel32", SetLastError = true)] static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, IntPtr nSize, out IntPtr lpNumberOfBytesRead); ちなみにIntPtrから取り出すならプリミティブ配列はMarshal.Copy、構造体配列はSafeBuffer.ReadArrayあたり 要素ごとにMarshal.PtrToStructureは遅いので…まぁ配列返すなら、そのままポインタで受け取った方が楽だね
| - C#, C♯, C#相談室 Part86 [転載禁止]©2ch.net
946 :945[sage]:2015/03/25(水) 20:13:25.76 ID:02yD7H6L - 嗚呼、一つ忘れてたけどint配列のポインタをIntPtrとして受け取るなら要素ごとにMarshal.ReadInt32でも良い
これはMarshal.PtrToStructureと違ってマーシャリングせず、内部でデリファレンスするだけなのでポインター並 …というかそのC++/CLIにはラッパーのみ?C#はDllImportで(自動で固定されて)直接ネイティブ呼べるよ?
|
|