c#調DLL
1324 ワード
c#C++パッケージのDLLを呼び出すのは確かに面倒なことで、特に他人が書いたDLLがデバッグに入れない場合は、ブラックボックスとしか思えないので、いろいろな方法で試してみましょう.経験を総括して,これからは回り道をしないでください.
DLLインタフェースの配列ポインタ
管理コードで割り当てられていないポインタは、管理配列に直接割り当てることはできません.単純なデータ構造に対して、配列ポインタは直接配列xxxを用いることができ、ただxxout[0]を用いることができ、またrefxxx[0]を用いることができる.例えば、dllにおけるint fun(unsigned char*a,int*b);c#int fun(ref byte c,ref int d)を宣言する.c#呼び出し時にbyte c,int[]d=new int[10]を定義し、値を割り当てる.fun(refc,refd[0])を呼び出す.ref/outの違い:入力と出力用refは、先に値を付けなければならない.出力用outのみです.構造体配列ポインタには、ref/outキーワードを使用する3つの方法が考えられます.この方法は、構造体配列ポインタに対して、配列の最初の要素しか返さない場合があります.理由は不明です.方法2:intptrとして定義し,marshalクラスでこのポインタを解析する.この方法は一般的に問題はない.
方法3:不安全コード、unsafeキーワードを使用し、ポインタを直接使用します.
DLLインタフェースの配列ポインタ
管理コードで割り当てられていないポインタは、管理配列に直接割り当てることはできません.単純なデータ構造に対して、配列ポインタは直接配列xxxを用いることができ、ただxxout[0]を用いることができ、またrefxxx[0]を用いることができる.例えば、dllにおけるint fun(unsigned char*a,int*b);c#int fun(ref byte c,ref int d)を宣言する.c#呼び出し時にbyte c,int[]d=new int[10]を定義し、値を割り当てる.fun(refc,refd[0])を呼び出す.ref/outの違い:入力と出力用refは、先に値を付けなければならない.出力用outのみです.構造体配列ポインタには、ref/outキーワードを使用する3つの方法が考えられます.この方法は、構造体配列ポインタに対して、配列の最初の要素しか返さない場合があります.理由は不明です.方法2:intptrとして定義し,marshalクラスでこのポインタを解析する.この方法は一般的に問題はない.
mStruct[] structArray= new mStruct[count];
int size = Marshal.SizeOf(typeof(mstruct));
IntPtr struArrayPtr = Marshal.AllocHGlobal(size * count);
dllFun(struArrayPtr);
for (int i= 0; i< count; i++)
{
IntPtr ptr = (IntPtr)((UInt32)struArrayPtr + i* size);
structArray[i] = (mStruct)Marshal.PtrToStructure(ptr, typeof(mStruct));
}
Marshal.FreeHGlobal(struArrayPtr);
方法3:不安全コード、unsafeキーワードを使用し、ポインタを直接使用します.