.Net CompactFramework on VB.netでアンマネージドDLLの操作について
タイトル長いな。
MSの参照サイト:クラス、構造体、および共用体のマーシャリング
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpguide/html/cpconmarshalingclassesstructuresunions.asp
まぁ、VB.net with CompactFrameworkは今回初めてだったので少しは躓くと思ったけど、
色んな所で引っかかったので覚え書き。
A.DLL関数のI/F構造体中の固定長配列について
定義出来ません。
通常の.net Framework環境においてなら、
http://www.microsoft.com/japan/msdn/net/vbtransitionguide/chapter4/chapter4_8.asp
この手順で出来ます。
但し、CompactFrameworkの簡易マーシャラではサポートされていません。
-
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpdnnetcomp/html/netcfadvinterop.asp
固定長配列が、構造体の「最終メンバ」であれば、この手順で出来ます。
ザックリ説明すると、
1.固定長配列を含まない形で、構造体を定義します。
2.固定長配列を含むサイズで、メモリを確保します。→ IntPtr型のポインタ値を取得
(AllocCoTaskMemメソッドがサポートされないので、LocalAllocを使用します)
3.1.の構造体を宣言します。
4.3.の構造体メンバへ必要な内容を設定します。
5.ローカルに構造体の固定長配列と同等の変数を宣言します。
6.5.へ必要な値を設定します。
7.4.で設定された内容を2.へコピーします。(Marshal.StructureToPtr)
8.6.で設定された内容を、2.が指すポインタの、構造体サイズ分進めた位置へコピーします。
(Marshal.Copy 等)
9.2.で取得したポインタを用いてDLL関数をCallします。
B.構造体中のポインタの扱いについて
Stringではなく、バイナリ値を扱うchar *や、int *、あるいはstructure *のポインタの場合。
・ローカル配列のアドレスを渡す手段は無い。
1.構造体のポインタメンバはIntPtr型とする。
2.Marshal.AllocCoTaskMemと同等の手順を踏み(A.2.と同様)、
IntPtr型のポインタを取得する。
3.2.で取得したアドレスを設定し、DLL関数をCallする。
4.2.のアドレスを使用し、ローカル配列へコピーする。
(Marshal.Copy、Marshal.PtrToStructure等)
C.構造体へのポインタが引数でメンバにOutパラメータが存在する場合
且つ、A.の固定長配列を含むなど、IntPtrでの操作を余儀なくされた場合
例えば、RECTへのポインタが引数で、In/Out引数だった場合。
(Left, top がIn, right, bottomがOutと仮定します)
Structure RECT{
Dim left as Long
Dim top as Long
Dim right as Long
Dim bottom as Long
}
A.の9までは一緒ですね。
1.ローカルにRECTを宣言します。
2.使用したポインタを1.へコピーします。(Marshal.PtrToStructure)
3.Outパラメータを確認します。
何か、メンドイ。